Compare commits
110 Commits
richard/cp
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e825110d38 | ||
|
|
22aae5d0d0 | ||
|
|
c98bb93514 | ||
|
|
58f1b8926c | ||
|
|
326b983ece | ||
|
|
89a5600be1 | ||
|
|
20da9cd09a | ||
|
|
9f779a64d0 | ||
|
|
790cc6f79e | ||
|
|
3370eaf12d | ||
|
|
c9878469fc | ||
|
|
ea280f9431 | ||
|
|
94fcfadce1 | ||
|
|
a6b052c570 | ||
|
|
adae3dda3e | ||
|
|
b6e53ca4c9 | ||
|
|
329cda4715 | ||
|
|
d63704c72d | ||
|
|
8f9c87075b | ||
|
|
817bbd1bea | ||
|
|
f6004a1c18 | ||
|
|
c4a954a7fc | ||
|
|
e5ffe6e0a3 | ||
|
|
268f811f9e | ||
|
|
4c2a2d568f | ||
|
|
f8c5695827 | ||
|
|
edcdfc8b02 | ||
|
|
8e3a03d2da | ||
|
|
af4c44a818 | ||
|
|
08480ce137 | ||
|
|
86a8f659fb | ||
|
|
cbb04aa9a2 | ||
|
|
e78d8f4fae | ||
|
|
775d8fbf70 | ||
|
|
bc39021cd7 | ||
|
|
24346a4542 | ||
|
|
b523616b1f | ||
|
|
858b088a88 | ||
|
|
8976c989c8 | ||
|
|
7711c43525 | ||
|
|
eee52ad1b9 | ||
|
|
958f70d5c2 | ||
|
|
c4da2a8ea4 | ||
|
|
5fa67a65f5 | ||
|
|
ba0ea42914 | ||
|
|
1f74024a30 | ||
|
|
00ce90cee0 | ||
|
|
7afa4e9ac9 | ||
|
|
c7d431a36a | ||
|
|
d541f56613 | ||
|
|
fbe07c4a16 | ||
|
|
295b9cfe1a | ||
|
|
0868999b5c | ||
|
|
c3d235b6e9 | ||
|
|
0de3bda383 | ||
|
|
a394fb1cee | ||
|
|
868f15a672 | ||
|
|
d1db5e590d | ||
|
|
ebf7587aaf | ||
|
|
e45d846331 | ||
|
|
35a3293531 | ||
|
|
66a85ef09e | ||
|
|
99777bd585 | ||
|
|
ad94684b23 | ||
|
|
58dc071b46 | ||
|
|
6f82083ea3 | ||
|
|
e8fa2f666a | ||
|
|
544382f313 | ||
|
|
46caa941d3 | ||
|
|
47fcc99853 | ||
|
|
846f717059 | ||
|
|
a32d1a2704 | ||
|
|
17926fe70b | ||
|
|
90799f5c60 | ||
|
|
525550ab86 | ||
|
|
4e8524d9d7 | ||
|
|
f3b73f60d0 | ||
|
|
6fc5cf31e9 | ||
|
|
2c45aa731c | ||
|
|
74f279d695 | ||
|
|
d72919e4e1 | ||
|
|
14e6d16d14 | ||
|
|
158fe9b698 | ||
|
|
e1d8661b40 | ||
|
|
386371c174 | ||
|
|
eb3af26867 | ||
|
|
c2d13700ac | ||
|
|
28294cf053 | ||
|
|
5b68014699 | ||
|
|
bc54a4d940 | ||
|
|
e96f22ab71 | ||
|
|
b009624902 | ||
|
|
3f66c028fa | ||
|
|
0fc60d48fa | ||
|
|
edebb9ad05 | ||
|
|
9a79c813e3 | ||
|
|
412788b120 | ||
|
|
456e2e81b3 | ||
|
|
68b9f19f7f | ||
|
|
294a2b69a0 | ||
|
|
2c265c9777 | ||
|
|
ac00b41a8e | ||
|
|
873cabd6a2 | ||
|
|
0c8d646e2d | ||
|
|
9dfe8d5128 | ||
|
|
460cfa38af | ||
|
|
94ade4b01f | ||
|
|
2459db6266 | ||
|
|
d274637d51 | ||
|
|
da332ed9e7 |
@ -50,7 +50,7 @@ BreakConstructorInitializersBeforeComma: false
|
||||
BreakConstructorInitializers: BeforeColon
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: true
|
||||
ColumnLimit: 120
|
||||
ColumnLimit: 120
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
CompactNamespaces: false
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
|
||||
@ -133,5 +133,6 @@ StatementMacros:
|
||||
TabWidth: 8
|
||||
UseCRLF: false
|
||||
UseTab: Never
|
||||
InsertBraces: true
|
||||
...
|
||||
|
||||
@ -3,6 +3,7 @@ Checks: 'clang-diagnostic-*,
|
||||
,clang-analyzer-*,
|
||||
,-clang-analyzer-security.insecureAPI.DeprecatedOrUnsafeBufferHandling,
|
||||
,-clang-analyzer-security.insecureAPI.strcpy,
|
||||
,-clang-analyzer-cplusplus.InnerPointer,
|
||||
,bugprone-*,
|
||||
,-bugprone-easily-swappable-parameters,
|
||||
,performance-*,
|
||||
@ -12,5 +13,10 @@ Checks: 'clang-diagnostic-*,
|
||||
,-readability-else-after-return,
|
||||
,-readability-magic-numbers,
|
||||
,-readability-function-cognitive-complexity,
|
||||
,-readability-uppercase-literal-suffix,
|
||||
,modernize-*,
|
||||
,-modernize-use-trailing-return-type,
|
||||
,-modernize-use-auto,
|
||||
,-cplusplus.InnerPointer,
|
||||
,-clang-diagnostic-ignored-optimization-argument,
|
||||
'
|
||||
|
||||
61
.github/workflows/actions/ubuntu-build-deps/action.yml
vendored
Normal file
61
.github/workflows/actions/ubuntu-build-deps/action.yml
vendored
Normal file
@ -0,0 +1,61 @@
|
||||
name: 'ubuntu build dependencies'
|
||||
description: 'install required build dependencies for ubuntu'
|
||||
inputs:
|
||||
SUDO:
|
||||
description: "set to true to run apt as root"
|
||||
required: false
|
||||
default: false
|
||||
|
||||
|
||||
runs:
|
||||
using: 'composite'
|
||||
steps:
|
||||
|
||||
- name: check if sudo is set
|
||||
shell: bash
|
||||
run: |
|
||||
if [ ${{ inputs.SUDO }} = true ]
|
||||
then
|
||||
AS_ROOT="sudo"
|
||||
else
|
||||
AS_ROOT=""
|
||||
fi
|
||||
echo "AS_ROOT=$AS_ROOT" >> $GITHUB_ENV
|
||||
|
||||
- name: apt update
|
||||
shell: bash
|
||||
run: ${{ env.AS_ROOT }} apt update
|
||||
|
||||
- name: install build tools
|
||||
shell: bash
|
||||
run: |
|
||||
${{ env.AS_ROOT }} apt install -y \
|
||||
build-essential \
|
||||
clang \
|
||||
clang-tidy \
|
||||
ninja-build \
|
||||
iwyu \
|
||||
pkgconf \
|
||||
wget
|
||||
if [ "$(lsb_release -s -r)x" == "16.04x" ]; then apt install -y clang-tools; fi
|
||||
|
||||
- name: install coturn dependencies
|
||||
shell: bash
|
||||
run: |
|
||||
${{ env.AS_ROOT }} apt install -y \
|
||||
libevent-dev \
|
||||
libssl-dev \
|
||||
libpq-dev \
|
||||
libsqlite3-dev \
|
||||
libhiredis-dev \
|
||||
libmongoc-dev \
|
||||
libmicrohttpd-dev
|
||||
if [ "$(lsb_release -s -r)x" == "16.04x" ]; then apt-get install -y libmariadb-client-lgpl-dev; fi
|
||||
if [ "$(lsb_release -s -r)x" == "16.04x" ]; then apt-get install -y libmariadb-dev; fi
|
||||
|
||||
- name: Prometheus Support
|
||||
shell: bash
|
||||
run: |
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb
|
||||
${{ env.AS_ROOT }} apt install -y ./libprom-dev-0.1.3-Linux.deb
|
||||
working-directory: /tmp/
|
||||
51
.github/workflows/clang-tidy.yml
vendored
51
.github/workflows/clang-tidy.yml
vendored
@ -1,51 +0,0 @@
|
||||
name: clang-tidy
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
jobs:
|
||||
clang-tidy:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
config: [Release]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install -y clang clang-tidy clang-tools ninja-build iwyu
|
||||
sudo apt install -y wget libevent-dev libssl-dev libpq-dev libmariadb-dev libsqlite3-dev libhiredis-dev libmongoc-dev libmicrohttpd-dev
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb
|
||||
sudo apt install -y ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.config }} -DCMAKE_EXPORT_COMPILE_COMMANDS=true
|
||||
|
||||
- name: Compile
|
||||
run: |
|
||||
cmake --build build --parallel --config ${{ matrix.config }}
|
||||
|
||||
# Implicitly requires build/compile_commands.json to exist
|
||||
- name: Run Clang Tidy
|
||||
run: |
|
||||
wget https://raw.githubusercontent.com/llvm/llvm-project/llvmorg-14.0.6/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
|
||||
chmod +x run-clang-tidy.py
|
||||
./run-clang-tidy.py -j $(nproc) -p build
|
||||
|
||||
# Implicitly requires build/compile_commands.json to exist
|
||||
- name: Run IWYU
|
||||
run: |
|
||||
wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/clang_14/iwyu_tool.py
|
||||
chmod +x iwyu_tool.py
|
||||
# iwyu_tool.py returns non-zero if any executions returned nonzero. Which... happens to be useless unless the project is already IWYU clean.
|
||||
./iwyu_tool.py -j $(nproc) -p build -- -Xiwyu --mapping_file=${GITHUB_WORKSPACE}/iwyu-ubuntu.imp || exit 0
|
||||
105
.github/workflows/clang.yml
vendored
Normal file
105
.github/workflows/clang.yml
vendored
Normal file
@ -0,0 +1,105 @@
|
||||
name: Clang
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
format:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/workflows/actions/ubuntu-build-deps
|
||||
with:
|
||||
SUDO: true
|
||||
|
||||
- name: Install `clang-format-15`
|
||||
run: sudo apt install -y clang-format-15
|
||||
- name: Prepare `clang-format`
|
||||
run: |
|
||||
set -e
|
||||
if which clang-format-15 2>&1 >/dev/null
|
||||
then
|
||||
sudo cp $(which clang-format-15) $(which clang-format)
|
||||
fi
|
||||
clang-format --version
|
||||
|
||||
- run: ./configure
|
||||
|
||||
- run: make lint
|
||||
|
||||
sanitize:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
sanitizer:
|
||||
- address,pointer-compare,pointer-subtract
|
||||
- thread
|
||||
env:
|
||||
CFLAGS: -fno-omit-frame-pointer -fstack-protector-all -fsanitize=${{ matrix.sanitizer }},bounds,enum -fsanitize-address-use-after-scope -fsanitize-address-use-after-return=always -fsanitize-recover=address -fsanitize-memory-track-origins=2
|
||||
CC: clang
|
||||
ASAN_OPTIONS: strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:detect_leaks=0:detect_invalid_pointer_pairs=1:halt_on_error=0
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/workflows/actions/ubuntu-build-deps
|
||||
with:
|
||||
SUDO: true
|
||||
|
||||
- run: ./configure
|
||||
- run: make -j $(nproc)
|
||||
|
||||
- run: make check
|
||||
|
||||
- run: ./run_tests.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_conf.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_prom.sh
|
||||
working-directory: examples/
|
||||
|
||||
tidy:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
config: ["Release"]
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install dependencies
|
||||
uses: ./.github/workflows/actions/ubuntu-build-deps
|
||||
with:
|
||||
SUDO: true
|
||||
|
||||
- name: Configure
|
||||
run: cmake -G Ninja -B build -DCMAKE_BUILD_TYPE=${{ matrix.config }}
|
||||
-DCMAKE_EXPORT_COMPILE_COMMANDS=true
|
||||
- name: Compile
|
||||
run: cmake --build build --parallel --config ${{ matrix.config }}
|
||||
|
||||
# Implicitly requires `build/compile_commands.json` to exist
|
||||
- name: Run `clang-tidy`
|
||||
run: |
|
||||
set -e
|
||||
wget https://raw.githubusercontent.com/llvm/llvm-project/llvmorg-14.0.6/clang-tools-extra/clang-tidy/tool/run-clang-tidy.py
|
||||
chmod +x run-clang-tidy.py
|
||||
./run-clang-tidy.py -j $(nproc) -p build
|
||||
|
||||
# Implicitly requires `build/compile_commands.json` to exist
|
||||
- name: Run IWYU
|
||||
run: |
|
||||
set -e
|
||||
wget https://raw.githubusercontent.com/include-what-you-use/include-what-you-use/clang_14/iwyu_tool.py
|
||||
chmod +x iwyu_tool.py
|
||||
# iwyu_tool.py returns non-zero if any executions returned nonzero. Which... happens to be useless unless the project is already IWYU clean.
|
||||
./iwyu_tool.py -j $(nproc) -p build -- -Xiwyu --mapping_file=${GITHUB_WORKSPACE}/iwyu-ubuntu.imp | grep -v "has correct" | uniq || exit 0
|
||||
62
.github/workflows/cmake.yaml
vendored
62
.github/workflows/cmake.yaml
vendored
@ -2,40 +2,46 @@ name: CMake
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
build:
|
||||
|
||||
runs-on: ubuntu-20.04
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
wget \
|
||||
libevent-dev \
|
||||
libssl-dev \
|
||||
libpq-dev libmariadb-dev libsqlite3-dev \
|
||||
libhiredis-dev \
|
||||
libmongoc-dev \
|
||||
libmicrohttpd-dev
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prometheus support
|
||||
run: |
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb && \
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb && \
|
||||
sudo apt install ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb && \
|
||||
rm ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb
|
||||
- name: Configure CMake
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
- name: apps tests
|
||||
run: cd examples && ./run_tests.sh
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
libevent-dev \
|
||||
libssl-dev \
|
||||
libpq-dev libmariadb-dev libsqlite3-dev \
|
||||
libhiredis-dev \
|
||||
libmongoc-dev \
|
||||
libmicrohttpd-dev \
|
||||
wget
|
||||
- uses: actions/checkout@v4
|
||||
- name: Prometheus support
|
||||
run: |
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb && \
|
||||
sudo apt install ./libprom-dev-0.1.3-Linux.deb && \
|
||||
rm ./libprom-dev-0.1.3-Linux.deb
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- run: ./run_tests.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_conf.sh
|
||||
working-directory: examples/
|
||||
|
||||
80
.github/workflows/codeql.yml
vendored
80
.github/workflows/codeql.yml
vendored
@ -1,67 +1,43 @@
|
||||
name: "CodeQL"
|
||||
name: CodeQL
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ 'master' ]
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
# The branches below must be a subset of the branches above
|
||||
branches: [ 'master' ]
|
||||
branches: ["master"]
|
||||
schedule:
|
||||
- cron: '6 13 * * 4'
|
||||
- cron: "6 13 * * 4"
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
BUILD_TYPE: Release
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
name: Analyze
|
||||
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
|
||||
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
actions: read
|
||||
contents: read
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
language: [ 'cpp' ]
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Use only 'java' to analyze code written in Java, Kotlin or both
|
||||
# Use only 'javascript' to analyze code written in JavaScript, TypeScript or both
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v4
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- if: matrix.language == 'cpp'
|
||||
name: Build C
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y --no-install-recommends --no-install-suggests autoconf ca-certificates coreutils g++ git libtool make pkg-config
|
||||
sudo apt-get install -y --no-install-recommends --no-install-suggests libevent-dev libssl-dev libpq-dev libmariadb-dev libsqlite3-dev libhiredis-dev libmongoc-dev libmicrohttpd-dev
|
||||
- name: Install dependencies
|
||||
uses: ./.github/workflows/actions/ubuntu-build-deps
|
||||
with:
|
||||
SUDO: true
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
# If you wish to specify custom queries, you can do so here or in a config file.
|
||||
# By default, queries listed here will override any specified in a config file.
|
||||
# Prefix the list here with "+" to use these queries and those in the config file.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v3
|
||||
with:
|
||||
languages: cpp
|
||||
|
||||
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# queries: security-extended,security-and-quality
|
||||
- name: Configure
|
||||
run: cmake -B ${{github.workspace}}/build -DCMAKE_BUILD_TYPE=${{env.BUILD_TYPE}}
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build --config ${{env.BUILD_TYPE}}
|
||||
|
||||
- if: matrix.language == 'cpp'
|
||||
name: Build C
|
||||
run: ./configure && make
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
- if: matrix.language != 'cpp'
|
||||
name: Autobuild
|
||||
uses: github/codeql-action/autobuild@v3
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v3
|
||||
|
||||
49
.github/workflows/compiler-sanitizers.yml
vendored
49
.github/workflows/compiler-sanitizers.yml
vendored
@ -1,49 +0,0 @@
|
||||
name: compiler-sanitizers
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
jobs:
|
||||
compiler-sanitizers:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
sanitizer: [ 'address,pointer-compare,pointer-subtract', 'thread' ]
|
||||
|
||||
env:
|
||||
CFLAGS: "-fno-omit-frame-pointer -fstack-protector-all -fsanitize=${{matrix.sanitizer}},bounds,enum -fsanitize-address-use-after-scope -fsanitize-address-use-after-return=always -fsanitize-recover=address -fsanitize-memory-track-origins=2"
|
||||
CC: "clang"
|
||||
ASAN_OPTIONS: "strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:detect_leaks=0:detect_invalid_pointer_pairs=1:halt_on_error=0"
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt install -y clang wget libevent-dev libssl-dev libpq-dev libmariadb-dev libsqlite3-dev libhiredis-dev libmongoc-dev libmicrohttpd-dev
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb
|
||||
sudo apt install -y ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
./configure
|
||||
|
||||
- name: Compile
|
||||
run: |
|
||||
make -j $(nproc)
|
||||
|
||||
- name: Check
|
||||
run: |
|
||||
make check
|
||||
|
||||
- name: Test
|
||||
run: |
|
||||
cd examples
|
||||
./run_tests.sh
|
||||
4
.github/workflows/docker.yml
vendored
4
.github/workflows/docker.yml
vendored
@ -1,4 +1,4 @@
|
||||
name: Docker CI
|
||||
name: Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
@ -281,7 +281,7 @@ jobs:
|
||||
working-directory: docker/coturn/
|
||||
|
||||
- name: Create GitHub release
|
||||
uses: softprops/action-gh-release@v1
|
||||
uses: softprops/action-gh-release@v2
|
||||
with:
|
||||
name: docker/${{ steps.semver.outputs.group1 }}
|
||||
body: |
|
||||
|
||||
29
.github/workflows/lint.yml
vendored
29
.github/workflows/lint.yml
vendored
@ -1,29 +0,0 @@
|
||||
name: Lint
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ $default-branch ]
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y \
|
||||
libevent-dev \
|
||||
libssl-dev \
|
||||
libpq-dev libmariadb-dev libsqlite3-dev \
|
||||
libhiredis-dev \
|
||||
libmongoc-dev \
|
||||
libmicrohttpd-dev \
|
||||
clang-format
|
||||
- uses: actions/checkout@v4
|
||||
- name: configure
|
||||
run: ./configure
|
||||
- name: lint
|
||||
run: clang-format --version && make lint
|
||||
70
.github/workflows/linux.yml
vendored
Normal file
70
.github/workflows/linux.yml
vendored
Normal file
@ -0,0 +1,70 @@
|
||||
name: Linux
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build + test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os:
|
||||
- amazonlinux:2023
|
||||
- ubuntu:20.04
|
||||
- ubuntu:22.04
|
||||
- ubuntu:24.04
|
||||
runs-on: ubuntu-latest
|
||||
container:
|
||||
image: ${{ matrix.os }}
|
||||
volumes:
|
||||
- ${{ contains('amazonlinux:2 ubuntu:16.04 ubuntu:18.04', matrix.os) && '/node20217:/node20217:rw,rshared' || ' ' }}
|
||||
- ${{ contains('amazonlinux:2 ubuntu:16.04 ubuntu:18.04', matrix.os) && '/node20217:/__e/node20:ro,rshared' || ' ' }}
|
||||
steps:
|
||||
- name: Install `yum` dependencies
|
||||
run: yum install -y gcc make gzip tar openssl-devel libevent-devel wget which
|
||||
if: ${{ contains(matrix.os, 'amazonlinux') }}
|
||||
|
||||
- name: Install Node.js 20 built against glibc 2.17 for GitHub Actions
|
||||
run: |
|
||||
set -ex
|
||||
which apt \
|
||||
&& apt update \
|
||||
&& apt install -y wget xz-utils
|
||||
which yum \
|
||||
&& yum install -y wget xz
|
||||
wget https://unofficial-builds.nodejs.org/download/release/v20.9.0/node-v20.9.0-linux-x64-glibc-217.tar.xz
|
||||
tar -xf node-v20.9.0-linux-x64-glibc-217.tar.xz --strip-components 1 -C /node20217
|
||||
ldd /__e/node20/bin/node
|
||||
working-directory: /tmp/
|
||||
if: ${{ contains('amazonlinux:2 ubuntu:16.04 ubuntu:18.04', matrix.os) }}
|
||||
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Install `apt` dependencies
|
||||
# Set env variable or otherwise `tzdata` package requires interaction.
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
uses: ./.github/workflows/actions/ubuntu-build-deps
|
||||
if: ${{ contains(matrix.os, 'ubuntu') }}
|
||||
|
||||
- run: ./configure
|
||||
- run: make
|
||||
|
||||
- run: make check
|
||||
|
||||
- run: ./run_tests.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_conf.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_prom.sh
|
||||
working-directory: examples/
|
||||
if: ${{ contains(matrix.os, 'ubuntu') }}
|
||||
101
.github/workflows/macos.yml
vendored
101
.github/workflows/macos.yml
vendored
@ -1,42 +1,85 @@
|
||||
name: C/C++ CI MacOS
|
||||
name: macOS
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ $default-branch ]
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
builds:
|
||||
runs-on: macos-12
|
||||
build:
|
||||
name: build + test
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ver: ["13", "14", "15"]
|
||||
runs-on: macos-${{ matrix.ver }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
# Unlink and re-link to prevent errors when github mac runner images
|
||||
# install python outside of brew, for example:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Relink `python` package in `brew`
|
||||
# Unlink and re-link to prevent errors when GitHub `macos` runner images
|
||||
# install `python` outside of `brew`, for example:
|
||||
# https://github.com/orgs/Homebrew/discussions/3895
|
||||
# https://github.com/actions/setup-python/issues/577
|
||||
# https://github.com/actions/runner-images/issues/6459
|
||||
# https://github.com/actions/runner-images/issues/6507
|
||||
# https://github.com/actions/runner-images/issues/2322
|
||||
brew list -1 | grep python | while read formula; do brew unlink $formula; brew link --overwrite $formula; done
|
||||
run: brew list -1
|
||||
| grep python
|
||||
| while read formula; do brew unlink $formula; brew link --overwrite $formula; done
|
||||
|
||||
brew update
|
||||
brew install \
|
||||
wget \
|
||||
pkg-config \
|
||||
libevent \
|
||||
openssl@1.1 \
|
||||
sqlite \
|
||||
hiredis \
|
||||
mongo-c-driver \
|
||||
libmicrohttpd
|
||||
- name: configure
|
||||
run: PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/local/opt/openssl@1.1/lib/pkgconfig ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: apps tests
|
||||
run: cd examples && ./run_tests.sh
|
||||
- run: brew update
|
||||
- run: brew install wget pkg-config libevent openssl@1.1 sqlite hiredis mongo-c-driver libmicrohttpd
|
||||
|
||||
- run: ./configure
|
||||
env:
|
||||
PKG_CONFIG_PATH: "${{ env.PKG_CONFIG_PATH }}:/usr/local/opt/openssl@1.1/lib/pkgconfig"
|
||||
- run: make
|
||||
|
||||
- run: make check
|
||||
|
||||
- run: ./run_tests.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_conf.sh
|
||||
working-directory: examples/
|
||||
|
||||
build-cmake:
|
||||
name: build + test cmake
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
ver: ["15"]
|
||||
runs-on: macos-${{ matrix.ver }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Relink `python` package in `brew`
|
||||
# Unlink and re-link to prevent errors when GitHub `macos` runner images
|
||||
# install `python` outside of `brew`, for example:
|
||||
# https://github.com/orgs/Homebrew/discussions/3895
|
||||
# https://github.com/actions/setup-python/issues/577
|
||||
# https://github.com/actions/runner-images/issues/6459
|
||||
# https://github.com/actions/runner-images/issues/6507
|
||||
# https://github.com/actions/runner-images/issues/2322
|
||||
run: brew list -1
|
||||
| grep python
|
||||
| while read formula; do brew unlink $formula; brew link --overwrite $formula; done
|
||||
|
||||
- run: brew update
|
||||
- run: brew install wget pkg-config libevent openssl@1.1 sqlite hiredis mongo-c-driver libmicrohttpd
|
||||
|
||||
- name: Configure
|
||||
run: cmake -B ${{github.workspace}}/build
|
||||
- name: Build
|
||||
run: cmake --build ${{github.workspace}}/build
|
||||
|
||||
- run: ./run_tests.sh
|
||||
working-directory: examples/
|
||||
- run: ./run_tests_conf.sh
|
||||
working-directory: examples/
|
||||
206
.github/workflows/mingw.yml
vendored
206
.github/workflows/mingw.yml
vendored
@ -1,126 +1,120 @@
|
||||
name: mingw
|
||||
name: MinGW
|
||||
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build
|
||||
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [windows-latest]
|
||||
# Customize the CMake build type here (Release, Debug, RelWithDebInfo, etc.)
|
||||
BUILD_TYPE: [Release, Debug]
|
||||
BUILD_SHARED_LIBS: [OFF]
|
||||
|
||||
os: ["windows"]
|
||||
# Customize the CMake build type here (`Release`, `Debug`, `RelWithDebInfo`, etc.)
|
||||
BUILD_TYPE: ["Release", "Debug"]
|
||||
BUILD_SHARED_LIBS: ["OFF"]
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
runs-on: ${{ matrix.os }}
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
env:
|
||||
BUILD_TYPE: ${{ matrix.BUILD_TYPE }}
|
||||
SOURCE_DIR: ${{github.workspace}}\.cache\source
|
||||
TOOSL_DIR: ${{github.workspace}}\.cache\tools
|
||||
INSTALL_DIR: ${{github.workspace}}\.cache\install_mingw_2022_02_15
|
||||
|
||||
SOURCE_DIR: ${{ github.workspace }}\.cache\source
|
||||
TOOSL_DIR: ${{ github.workspace }}\.cache\tools
|
||||
INSTALL_DIR: ${{ github.workspace }}\.cache\install_mingw_2022_02_15
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
#with:
|
||||
#fetch-depth: 0
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: pacman
|
||||
env:
|
||||
PATH: C:\msys64\usr\bin
|
||||
run: |
|
||||
C:\msys64\usr\bin\pacman.exe -S --noconfirm ^
|
||||
mingw-w64-x86_64-cmake ^
|
||||
mingw-w64-x86_64-make ^
|
||||
mingw-w64-x86_64-nsis ^
|
||||
mingw-w64-x86_64-gcc ^
|
||||
mingw-w64-x86_64-zlib ^
|
||||
mingw-w64-x86_64-openssl ^
|
||||
mingw-w64-x86_64-libevent ^
|
||||
mingw-w64-x86_64-sqlite3 ^
|
||||
mingw-w64-x86_64-hiredis ^
|
||||
mingw-w64-x86_64-postgresql ^
|
||||
mingw-w64-x86_64-libmicrohttpd ^
|
||||
git base-devel
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
C:\msys64\usr\bin\pacman.exe -S --noconfirm ^
|
||||
mingw-w64-x86_64-cmake ^
|
||||
mingw-w64-x86_64-make ^
|
||||
mingw-w64-x86_64-nsis ^
|
||||
mingw-w64-x86_64-gcc ^
|
||||
mingw-w64-x86_64-zlib ^
|
||||
mingw-w64-x86_64-openssl ^
|
||||
mingw-w64-x86_64-libevent ^
|
||||
mingw-w64-x86_64-sqlite3 ^
|
||||
mingw-w64-x86_64-hiredis ^
|
||||
mingw-w64-x86_64-postgresql ^
|
||||
mingw-w64-x86_64-libmicrohttpd ^
|
||||
git base-devel
|
||||
env:
|
||||
PATH: C:\msys64\usr\bin
|
||||
|
||||
- name: make_directory
|
||||
run: |
|
||||
cmake -E make_directory ${{env.SOURCE_DIR}}
|
||||
cmake -E make_directory ${{env.TOOSL_DIR}}
|
||||
cmake -E make_directory ${{env.INSTALL_DIR}}
|
||||
- name: Create directories
|
||||
run: |
|
||||
cmake -E make_directory ${{ env.SOURCE_DIR }}
|
||||
cmake -E make_directory ${{ env.TOOSL_DIR }}
|
||||
cmake -E make_directory ${{ env.INSTALL_DIR }}
|
||||
|
||||
- name: Cache installed
|
||||
uses: actions/cache@v4
|
||||
id: cache-installed
|
||||
with:
|
||||
path: |
|
||||
${{env.INSTALL_DIR}}
|
||||
key: coturn-cache-installed-mingw
|
||||
- name: Cache installed
|
||||
uses: actions/cache@v4
|
||||
id: cache-installed
|
||||
with:
|
||||
path: ${{ env.INSTALL_DIR }}
|
||||
key: coturn-cache-installed-mingw
|
||||
|
||||
- name: build prometheus
|
||||
if: false
|
||||
working-directory: ${{env.SOURCE_DIR}}
|
||||
env:
|
||||
MSYSTEM: MINGW64
|
||||
PATH: C:\msys64\mingw64\bin;C:\msys64\usr\bin
|
||||
run: |
|
||||
cd ${{env.SOURCE_DIR}}
|
||||
git clone https://github.com/digitalocean/prometheus-client-c.git
|
||||
cd prometheus-client-c/prom
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G"MinGW Makefiles" ^
|
||||
-DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{env.INSTALL_DIR}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target install
|
||||
cd ${{env.SOURCE_DIR}}/prometheus-client-c/promhttp
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G"MinGW Makefiles" ^
|
||||
-DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{env.INSTALL_DIR}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target install
|
||||
- name: Build Prometheus
|
||||
run: |
|
||||
cd ${{ env.SOURCE_DIR }}
|
||||
git clone https://github.com/digitalocean/prometheus-client-c.git
|
||||
cd prometheus-client-c/prom
|
||||
mkdir build
|
||||
cd build
|
||||
cmake .. -G"MinGW Makefiles" ^
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} ^
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.BUILD_TYPE }} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{ env.INSTALL_DIR }}
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }}
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }} --target install
|
||||
env:
|
||||
MSYSTEM: MINGW64
|
||||
PATH: C:\msys64\mingw64\bin;C:\msys64\usr\bin
|
||||
working-directory: ${{ env.SOURCE_DIR }}
|
||||
if: ${{ false }}
|
||||
|
||||
- name: build coturn
|
||||
working-directory: ${{github.workspace}}
|
||||
env:
|
||||
MSYSTEM: MINGW64
|
||||
PATH: C:\msys64\mingw64\bin;C:\msys64\usr\bin
|
||||
Prometheus_ROOT: ${{env.INSTALL_DIR}}
|
||||
run: |
|
||||
cmake -E make_directory build
|
||||
cd build
|
||||
cmake .. -G"MinGW Makefiles" ^
|
||||
-DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target install
|
||||
- name: Build Coturn
|
||||
run: |
|
||||
cmake -E make_directory build
|
||||
cd build
|
||||
cmake .. -G"MinGW Makefiles" ^
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} ^
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.BUILD_TYPE }} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/build/install
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }}
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }} --target install
|
||||
env:
|
||||
MSYSTEM: MINGW64
|
||||
PATH: C:\msys64\mingw64\bin;C:\msys64\usr\bin
|
||||
Prometheus_ROOT: ${{ env.INSTALL_DIR }}
|
||||
working-directory: ${{ github.workspace }}
|
||||
|
||||
- name: Package
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
working-directory: ${{github.workspace}}\build
|
||||
run: |
|
||||
copy /Y ${{env.INSTALL_DIR}}\bin\*.dll install\bin
|
||||
copy /Y ${{env.INSTALL_DIR}}\lib\*.dll install\bin
|
||||
copy /Y ${{env.RUNVCPKG_VCPKG_ROOT}}\installed\${{env.RUNVCPKG_VCPKG_TRIPLET_OUT}}\bin\*.dll install\bin
|
||||
7z a coturn_windows_mingw.zip ${{github.workspace}}\build\install\*
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target package
|
||||
- name: Package
|
||||
run: |
|
||||
copy /Y ${{ env.INSTALL_DIR }}\bin\*.dll install\bin
|
||||
copy /Y ${{ env.INSTALL_DIR }}\lib\*.dll install\bin
|
||||
copy /Y ${{ env.RUNVCPKG_VCPKG_ROOT }}\installed\${{ env.RUNVCPKG_VCPKG_TRIPLET_OUT }}\bin\*.dll install\bin
|
||||
7z a coturn_windows_mingw.zip ${{ github.workspace }}\build\install\*
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }} --target package
|
||||
working-directory: ${{ github.workspace }}\build
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
|
||||
- name: update
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coturn_mingw_${{ matrix.os }}
|
||||
path: |
|
||||
${{github.workspace}}\build\coturn_windows_mingw.zip
|
||||
${{github.workspace}}\build\coturn*.exe
|
||||
${{github.workspace}}\build\coturn*.md5
|
||||
- name: Update artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coturn_mingw_${{ matrix.os }}
|
||||
path: |
|
||||
${{ github.workspace }}\build\coturn_windows_mingw.zip
|
||||
${{ github.workspace }}\build\coturn*.exe
|
||||
${{ github.workspace }}\build\coturn*.md5
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
|
||||
78
.github/workflows/msvc-analyzer.yml
vendored
78
.github/workflows/msvc-analyzer.yml
vendored
@ -1,78 +0,0 @@
|
||||
name: msvc-analyzer
|
||||
|
||||
on:
|
||||
push:
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
jobs:
|
||||
msvc-analyzer:
|
||||
runs-on: windows-latest
|
||||
|
||||
permissions:
|
||||
# required for all codeql to report detected outcomes
|
||||
security-events: write
|
||||
|
||||
strategy:
|
||||
matrix:
|
||||
BUILD_TYPE: [Release]
|
||||
BUILD_SHARED_LIBS: [OFF]
|
||||
VCPKG_PLATFORM_TOOLSET: [v143]
|
||||
CMAKE_GENERATOR_PLATFORM: [x64]
|
||||
|
||||
env:
|
||||
SOURCE_DIR: ${{github.workspace}}\.cache\source
|
||||
TOOLS_DIR: ${{github.workspace}}\.cache\tools
|
||||
INSTALL_DIR: ${{github.workspace}}\.cache\install_msvc_x64-windows_${{matrix.BUILD_TYPE}}
|
||||
VCPKGGITCOMMITID: 53bef8994c541b6561884a8395ea35715ece75db
|
||||
VCPKG_PLATFORM_TOOLSET: ${{matrix.VCPKG_PLATFORM_TOOLSET}}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{matrix.CMAKE_GENERATOR_PLATFORM}}
|
||||
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: make directory
|
||||
run: |
|
||||
cmake -E make_directory ${{env.SOURCE_DIR}}
|
||||
cmake -E make_directory ${{env.TOOLS_DIR}}
|
||||
cmake -E make_directory ${{env.INSTALL_DIR}}
|
||||
|
||||
- name: run-vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
# If not using a submodule for vcpkg sources, this specifies which commit
|
||||
# id must be checkout from a Git repo. It must not set if using a submodule
|
||||
# for vcpkg.
|
||||
vcpkgGitCommitId: '${{ env.VCPKGGITCOMMITID }}'
|
||||
|
||||
- name: Configure (MSVC)
|
||||
run: |
|
||||
cmake -B build ^
|
||||
-A ${{matrix.CMAKE_GENERATOR_PLATFORM}} ^
|
||||
-T ${{matrix.VCPKG_PLATFORM_TOOLSET}} ^
|
||||
-DWITH_MYSQL=OFF ^
|
||||
-DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_ROOT}}/scripts/buildsystems/vcpkg.cmake
|
||||
|
||||
- name: Initialize MSVC Code Analysis
|
||||
uses: microsoft/msvc-code-analysis-action@v0.1.1
|
||||
# Provide a unique ID to access the sarif output path
|
||||
id: run-analysis
|
||||
with:
|
||||
cmakeBuildDirectory: build
|
||||
buildConfiguration: ${{ matrix.BUILD_TYPE }}
|
||||
# Ruleset file that will determine what checks will be run
|
||||
ruleset: NativeRecommendedRules.ruleset
|
||||
|
||||
# Upload SARIF file to GitHub Code Scanning Alerts
|
||||
- name: Upload SARIF to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: ${{ steps.run-analysis.outputs.sarif }}
|
||||
205
.github/workflows/msvc.yml
vendored
205
.github/workflows/msvc.yml
vendored
@ -1,99 +1,160 @@
|
||||
name: msvc
|
||||
name: MSVC
|
||||
|
||||
on: [push]
|
||||
on:
|
||||
push:
|
||||
branches: ["master"]
|
||||
tags: ["4.*"]
|
||||
pull_request:
|
||||
branches: ["master"]
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
VCPKGGITCOMMITID: 53bef8994c541b6561884a8395ea35715ece75db
|
||||
|
||||
jobs:
|
||||
compile:
|
||||
name: ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}}
|
||||
|
||||
code-analysis:
|
||||
name: code analysis (windows-vc-${{ matrix.VCPKG_PLATFORM_TOOLSET }}-${{ matrix.CMAKE_GENERATOR_PLATFORM }}-${{ matrix.BUILD_TYPE }}-${{ matrix.BUILD_SHARED_LIBS }})
|
||||
runs-on: windows-latest
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
BUILD_TYPE: [Release, Debug]
|
||||
BUILD_SHARED_LIBS: [OFF, ON]
|
||||
#VCPKG_PLATFORM_TOOLSET: [v143, v142, v141]
|
||||
CMAKE_GENERATOR_PLATFORM: [x64, Win32]
|
||||
os: [windows-latest]
|
||||
BUILD_TYPE: [Release]
|
||||
BUILD_SHARED_LIBS: [OFF]
|
||||
VCPKG_PLATFORM_TOOLSET: [v143]
|
||||
CMAKE_GENERATOR_PLATFORM: [x64]
|
||||
env:
|
||||
SOURCE_DIR: ${{ github.workspace }}\.cache\source
|
||||
TOOLS_DIR: ${{ github.workspace }}\.cache\tools
|
||||
INSTALL_DIR: ${{ github.workspace }}\.cache\install_msvc_x64-windows_${{ matrix.BUILD_TYPE }}
|
||||
VCPKG_PLATFORM_TOOLSET: ${{ matrix.VCPKG_PLATFORM_TOOLSET }}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{ matrix.CMAKE_GENERATOR_PLATFORM }}
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
permissions:
|
||||
security-events: write # required for all CodeQL to report detected outcomes
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Create directories
|
||||
run: |
|
||||
cmake -E make_directory ${{ env.SOURCE_DIR }}
|
||||
cmake -E make_directory ${{ env.TOOLS_DIR }}
|
||||
cmake -E make_directory ${{ env.INSTALL_DIR }}
|
||||
|
||||
- name: run-vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
# If not using a submodule for vcpkg sources, this specifies which commit
|
||||
# id must be checkout from a Git repo. It must not set if using a submodule
|
||||
# for vcpkg.
|
||||
vcpkgGitCommitId: '${{ env.VCPKGGITCOMMITID }}'
|
||||
|
||||
- name: Configure
|
||||
run: |
|
||||
cmake -B build ^
|
||||
-A ${{ matrix.CMAKE_GENERATOR_PLATFORM }} ^
|
||||
-T ${{ matrix.VCPKG_PLATFORM_TOOLSET }} ^
|
||||
-DWITH_MYSQL=OFF ^
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} ^
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.BUILD_TYPE }} ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
|
||||
|
||||
- name: Initialize MSVC Code Analysis
|
||||
uses: microsoft/msvc-code-analysis-action@v0.1.1
|
||||
# Provide a unique ID to access the SARIF output path.
|
||||
id: run-analysis
|
||||
with:
|
||||
cmakeBuildDirectory: build
|
||||
buildConfiguration: ${{ matrix.BUILD_TYPE }}
|
||||
# Ruleset file that will determine what checks will be run.
|
||||
ruleset: NativeRecommendedRules.ruleset
|
||||
|
||||
# Upload SARIF file to GitHub Code Scanning Alerts
|
||||
- name: Upload SARIF to GitHub
|
||||
uses: github/codeql-action/upload-sarif@v3
|
||||
with:
|
||||
sarif_file: ${{ steps.run-analysis.outputs.sarif }}
|
||||
|
||||
compile:
|
||||
name: compile (${{ matrix.os }}-vc-${{ matrix.VCPKG_PLATFORM_TOOLSET }}-${{ matrix.CMAKE_GENERATOR_PLATFORM }}-${{ matrix.BUILD_TYPE }}-${{ matrix.BUILD_SHARED_LIBS }})
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
BUILD_TYPE: ["Release", "Debug"]
|
||||
BUILD_SHARED_LIBS: ["OFF", "ON"]
|
||||
CMAKE_GENERATOR_PLATFORM: ["x64", "Win32"]
|
||||
os: ["windows"]
|
||||
include:
|
||||
# MSVC 2022
|
||||
- triplet: x64-windows
|
||||
VCPKG_PLATFORM_TOOLSET: v143
|
||||
CMAKE_GENERATOR_PLATFORM: x64
|
||||
|
||||
- triplet: x86-windows
|
||||
VCPKG_PLATFORM_TOOLSET: v143
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
|
||||
# MSVC 2019
|
||||
- triplet: x86-windows
|
||||
VCPKG_PLATFORM_TOOLSET: v142
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
|
||||
# MSVC 2017
|
||||
- triplet: x86-windows
|
||||
VCPKG_PLATFORM_TOOLSET: v141
|
||||
CMAKE_GENERATOR_PLATFORM: Win32
|
||||
|
||||
runs-on: ${{matrix.os}}
|
||||
|
||||
runs-on: ${{ matrix.os }}-latest
|
||||
env:
|
||||
SOURCE_DIR: ${{github.workspace}}\.cache\source
|
||||
TOOLS_DIR: ${{github.workspace}}\.cache\tools
|
||||
INSTALL_DIR: ${{github.workspace}}\.cache\install_msvc_${{matrix.triplet}}_${{matrix.BUILD_TYPE}}
|
||||
VCPKGGITCOMMITID: 53bef8994c541b6561884a8395ea35715ece75db
|
||||
VCPKG_PLATFORM_TOOLSET: ${{matrix.VCPKG_PLATFORM_TOOLSET}}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{matrix.CMAKE_GENERATOR_PLATFORM}}
|
||||
|
||||
SOURCE_DIR: ${{ github.workspace }}\.cache\source
|
||||
TOOLS_DIR: ${{ github.workspace }}\.cache\tools
|
||||
INSTALL_DIR: ${{ github.workspace }}\.cache\install_msvc_${{matrix.triplet}}_${{matrix.BUILD_TYPE}}
|
||||
VCPKG_PLATFORM_TOOLSET: ${{ matrix.VCPKG_PLATFORM_TOOLSET }}
|
||||
CMAKE_GENERATOR_PLATFORM: ${{ matrix.CMAKE_GENERATOR_PLATFORM }}
|
||||
defaults:
|
||||
run:
|
||||
shell: cmd
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: make directory
|
||||
run: |
|
||||
cmake -E make_directory ${{env.SOURCE_DIR}}
|
||||
cmake -E make_directory ${{env.TOOLS_DIR}}
|
||||
cmake -E make_directory ${{env.INSTALL_DIR}}
|
||||
- name: Create directories
|
||||
run: |
|
||||
cmake -E make_directory ${{ env.SOURCE_DIR }}
|
||||
cmake -E make_directory ${{ env.TOOLS_DIR }}
|
||||
cmake -E make_directory ${{ env.INSTALL_DIR }}
|
||||
|
||||
- name: run-vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
# If not using a submodule for vcpkg sources, this specifies which commit
|
||||
# id must be checkout from a Git repo. It must not set if using a submodule
|
||||
# for vcpkg.
|
||||
vcpkgGitCommitId: '${{ env.VCPKGGITCOMMITID }}'
|
||||
- name: run-vcpkg
|
||||
uses: lukka/run-vcpkg@v11
|
||||
with:
|
||||
# If not using a submodule for vcpkg sources, this specifies which commit
|
||||
# id must be checkout from a Git repo. It must not set if using a submodule
|
||||
# for vcpkg.
|
||||
vcpkgGitCommitId: '${{ env.VCPKGGITCOMMITID }}'
|
||||
|
||||
- name: build coturn
|
||||
run: |
|
||||
cmake -E make_directory ${{github.workspace}}/build
|
||||
cd ${{github.workspace}}/build
|
||||
cmake ${{github.workspace}} ^
|
||||
-A ${{matrix.CMAKE_GENERATOR_PLATFORM}} ^
|
||||
-T ${{matrix.VCPKG_PLATFORM_TOOLSET}} ^
|
||||
-DWITH_MYSQL=OFF ^
|
||||
-DBUILD_SHARED_LIBS=${{matrix.BUILD_SHARED_LIBS}} ^
|
||||
-DCMAKE_BUILD_TYPE=${{matrix.BUILD_TYPE}} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{env.VCPKG_ROOT}}/scripts/buildsystems/vcpkg.cmake
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}}
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target install
|
||||
- name: Build Coturn
|
||||
run: |
|
||||
cmake -E make_directory ${{ github.workspace }}/build
|
||||
cd ${{ github.workspace }}/build
|
||||
cmake ${{ github.workspace }} ^
|
||||
-A ${{ matrix.CMAKE_GENERATOR_PLATFORM }} ^
|
||||
-T ${{ matrix.VCPKG_PLATFORM_TOOLSET }} ^
|
||||
-DWITH_MYSQL=OFF ^
|
||||
-DBUILD_SHARED_LIBS=${{ matrix.BUILD_SHARED_LIBS }} ^
|
||||
-DCMAKE_BUILD_TYPE=${{ matrix.BUILD_TYPE }} ^
|
||||
-DCMAKE_INSTALL_PREFIX=${{ github.workspace }}/build/install ^
|
||||
-DCMAKE_TOOLCHAIN_FILE=${{ env.VCPKG_ROOT }}/scripts/buildsystems/vcpkg.cmake
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }}
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }} --target install
|
||||
|
||||
- name: Package
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
working-directory: ${{github.workspace}}\build
|
||||
run: |
|
||||
7z a coturn_windows_msvc.zip ${{github.workspace}}\build\install\*
|
||||
cmake --build . --config ${{matrix.BUILD_TYPE}} --target package
|
||||
- name: Package
|
||||
run: |
|
||||
7z a coturn_windows_msvc.zip ${{ github.workspace }}\build\install\*
|
||||
cmake --build . --config ${{ matrix.BUILD_TYPE }} --target package
|
||||
working-directory: ${{ github.workspace }}\build
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
|
||||
- name: update
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coturn_msvc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_SHARED_LIBS}}
|
||||
path: |
|
||||
${{github.workspace}}\build\coturn_windows_msvc.zip
|
||||
${{github.workspace}}\build\coturn*.exe
|
||||
${{github.workspace}}\build\coturn*.md5
|
||||
- name: Update artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: coturn_msvc-${{ matrix.VCPKG_PLATFORM_TOOLSET }}-${{ matrix.CMAKE_GENERATOR_PLATFORM }}-${{ matrix.BUILD_SHARED_LIBS }}
|
||||
path: |
|
||||
${{ github.workspace }}\build\coturn_windows_msvc.zip
|
||||
${{ github.workspace }}\build\coturn*.exe
|
||||
${{ github.workspace }}\build\coturn*.md5
|
||||
if: ${{ matrix.BUILD_TYPE == 'Release' }}
|
||||
|
||||
48
.github/workflows/tests.yml
vendored
48
.github/workflows/tests.yml
vendored
@ -1,48 +0,0 @@
|
||||
name: C/C++ CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ $default-branch ]
|
||||
pull_request:
|
||||
types: [ opened, reopened, synchronize ]
|
||||
|
||||
jobs:
|
||||
builds:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ 'ubuntu:16.04', 'ubuntu:20.04', 'ubuntu:22.04' ]
|
||||
runs-on: ubuntu-latest
|
||||
container: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: Install dependencies
|
||||
# Set env variable or otherwise tzdata package requires interaction
|
||||
env:
|
||||
DEBIAN_FRONTEND: noninteractive
|
||||
run: |
|
||||
apt-get update
|
||||
apt-get install -y \
|
||||
build-essential pkgconf
|
||||
apt-get install -y \
|
||||
wget \
|
||||
libevent-dev \
|
||||
libssl-dev \
|
||||
libpq-dev libsqlite3-dev \
|
||||
libhiredis-dev \
|
||||
libmongoc-dev \
|
||||
libmicrohttpd-dev
|
||||
if [ ${{ matrix.os }} = 'ubuntu:16.04' ]; then apt-get install -y libmariadb-client-lgpl-dev; fi
|
||||
if [ ${{ matrix.os }} != 'ubuntu:16.04' ]; then apt-get install -y libmariadb-dev; fi
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb && \
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb && \
|
||||
apt install ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb && \
|
||||
rm ./libprom-dev-0.1.3-Linux.deb ./libpromhttp-dev-0.1.3-Linux.deb
|
||||
- uses: actions/checkout@v3
|
||||
- name: configure
|
||||
run: ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: make check
|
||||
run: make check
|
||||
- name: apps tests
|
||||
run: cd examples && ./run_tests.sh
|
||||
32
AUTHORS.md
32
AUTHORS.md
@ -1,8 +1,11 @@
|
||||
Thanks to the following contributors (in alphabetical order):
|
||||
|
||||
- Aaron Bird <25508292+Aaron-Bird@users.noreply.github.com>
|
||||
- Alessandro Polidori <alessandro.polidori@nethesis.it>
|
||||
- Alex Gustafsson <89969483+alexg-axis@users.noreply.github.com>
|
||||
- Alexander N <a@a>
|
||||
- Alexander Terczka <alex@mail.at>
|
||||
- Alexander Udovichenko <udovichenko48@gmail.com>
|
||||
- Antony Dovgal <tony@daylessday.org>
|
||||
- Arjun <36335769+0x34d@users.noreply.github.com>
|
||||
- Arne Georg Gisnås Gleditsch <argggh@appear.in>
|
||||
@ -14,19 +17,24 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Byron Clark <byron@theclarkfamily.name>
|
||||
- Camden Narzt <c.narzt@me.com>
|
||||
- Carsten Bock <carsten@ng-voice.com>
|
||||
- Cédric DIJOUX <45537432+PrinceChoco@users.noreply.github.com>
|
||||
- Cédric Krier <ced@b2ck.com>
|
||||
- Chai-Shi <changchaishi@gmail.com>
|
||||
- Corey Cole <coreyleoc@gmail.com>
|
||||
- Cybermilitia <Cybermilitia@users.noreply.github.com>
|
||||
- Daniil Meitis <30820460+dsmeytis@users.noreply.github.com>
|
||||
- Daniil Meitis <daniil.meitis@viber.com>
|
||||
- Danilo Bargen <mail@dbrgn.ch>
|
||||
- Dave Lambley <dave@lambley.me.uk>
|
||||
- Dave Lambley <github@davel.me.uk>
|
||||
- David Florness <david@florness.com>
|
||||
- David Smitmanis <davidsm@axis.com>
|
||||
- David-dp- <David-dp-@users.noreply.github.com>
|
||||
- Domenico Briganti <domenico.briganti@osys.it>
|
||||
- Emil Ljungdahl <111423223+pando-emil@users.noreply.github.com>
|
||||
- Erdem Duman <erdemduman23@gmail.com>
|
||||
- Erik Moqvist <erik.moqvist@axis.com>
|
||||
- Evgeny Khramtsov <xramtsov@gmail.com>
|
||||
- Feral Interactive <noreply@feralinteractive.com>
|
||||
- Gautier HUSSON <g.husson_git@liberasys.com>
|
||||
- Giacomo Vacca <gvacca@subspace.com>
|
||||
@ -34,12 +42,14 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Greg Fodor <gfodor@gmail.com>
|
||||
- Gregor Jasny <gjasny@googlemail.com>
|
||||
- Gustavo Garcia <gustavogb@gmail.com>
|
||||
- Gustavo Garcia <gustavogb@mail.com>
|
||||
- Haseeb Abdul Qadir <haseebq@jumpdesktop.com>
|
||||
- Hristo Venev <hristo@venev.name>
|
||||
- Hui Kang <kangh@us.ibm.com>
|
||||
- Hyorin Choi <17173216+hyorin@users.noreply.github.com>
|
||||
- Ilya Kisleyko <osterik@gmail.com>
|
||||
- James Huang <hng.jms@gmail.com>
|
||||
- Jan Brasna <1784648+janbrasna@users.noreply.github.com>
|
||||
- Jasper <jasper@jasperhugo.com>
|
||||
- Jens Elkner <jel+coturn@cs.ovgu.de>
|
||||
- Jens Elkner <jel+git@iks.cs.uni-magdeburg.de>
|
||||
@ -49,6 +59,7 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Johannes Weberhofer <jweberhofer@weberhofer.at>
|
||||
- Jonathan GIBERT <Jonathan.GIBERT@iconsultants.fr>
|
||||
- JooYoung <qkdlql@naver.com>
|
||||
- Jorge <46056498+jorgectf@users.noreply.github.com>
|
||||
- Juan Navarro <juan.navarro@gmx.es>
|
||||
- KORAY VATANSEVER <koray.vatansever@turkcell.com.tr>
|
||||
- KORAY VATANSEVER <ttkvatansever@TC08966777>
|
||||
@ -67,14 +78,17 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Mészáros Mihály <bakfitty@gmail.com>
|
||||
- Mészáros Mihály <misi@majd.eu>
|
||||
- Mészáros Mihály <misi@niif.hu>
|
||||
- Michael Jones <jonesmz@users.noreply.github.com>
|
||||
- Michal Biskup <eiver@eiver.pl>
|
||||
- Miquel Ortega <miquel@syncrtc.com>
|
||||
- Molly Miller <33266253+sysvinit@users.noreply.github.com>
|
||||
- Molly Miller <molly.miller@wire.com>
|
||||
- Mustafa Bingül <bnglmstf@gmail.com>
|
||||
- NO NAME <45446340+linwenchen@users.noreply.github.com>
|
||||
- NeoCat <neocat@neocat.jp>
|
||||
- Nicolas Edet <nicedet@cisco.com>
|
||||
- Nikolay Lanets <n.lanets@modxclub.ru>
|
||||
- Nikolayshcx <77790944+Nikolayshcx@users.noreply.github.com>
|
||||
- Oleg Moskalenko <mom040267@gmail.com>
|
||||
- Orsiris de Jong <ozy@netpower.fr>
|
||||
- Oskar Niburski <oskarniburski@gmail.com>
|
||||
@ -90,8 +104,10 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Prashanth Rajaram <prashanthr@users.noreply.github.com>
|
||||
- RIORAO <lah.messagebox@gmail.com>
|
||||
- Richard Garnier <richard@bitcraft.co.jp>
|
||||
- Richard Russo <richard@signal.org>
|
||||
- Robert Scheck <robert-scheck@users.noreply.github.com>
|
||||
- Robert Scheck <robert@fedoraproject.org>
|
||||
- Robert Silén <robert.silen@mariadb.org>
|
||||
- Robert Tupelo-Schneck <schneck@cnri.reston.va.us>
|
||||
- Rozhuk Ivan <rozhuk.im@gmail.com>
|
||||
- Ruben Barkow-Kuder <rubo77@users.noreply.github.com>
|
||||
@ -100,28 +116,41 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- Sandro Gauci <sandro@enablesecurity.com>
|
||||
- Scott Godin <sgodin@sipspectrum.com>
|
||||
- Sebastian Kemper <sebastian_ml@gmx.net>
|
||||
- Sergey Radionov <RSATom@gmail.com>
|
||||
- Sergey Safarov <s.safarov@gmail.com>
|
||||
- Serhii Charykov <laammaar@gmail.com>
|
||||
- Shu Muto <shu.mutow@gmail.com>
|
||||
- Shu Muto <shu.mutow@nec.com>
|
||||
- Stefan Junker <1181362+steveej@users.noreply.github.com>
|
||||
- Stefan Sundin <git@stefansundin.com>
|
||||
- Steffen Moser <public@steffen-moser.de>
|
||||
- Steffen Moser <steffen.moser@uni-ulm.de>
|
||||
- Subhra264 <chakrabortysubhradeep556@gmail.com>
|
||||
- Sven Tennie <sven.tennie@gmail.com>
|
||||
- Thibaut ACKERMANN <thib-ack@users.noreply.github.com>
|
||||
- Thibaut Ackermann <thibaut.ackermann@al-enterprise.com>
|
||||
- Thibaut Ackermann <thibaut.ackermann@alcatel-lucent.com>
|
||||
- Tom Bevan <thehorrorthehorror@gmail.com>
|
||||
- Wittmer, Christian <chris@computersalat.de>
|
||||
- Wuelber Castillo <wuelber.castillo@gmail.com>
|
||||
- Yoshiki Kadoshita <sublimer.me@gmail.com>
|
||||
- Zebadiah Long <zeb@noblewhale.com>
|
||||
- Zoey <zoey@z0ey.de>
|
||||
- ashamedbit <muralianiruddhan@gmail.com>
|
||||
- bpcurse <29312856+bpcurse@users.noreply.github.com>
|
||||
- brevilo <brevilo@users.noreply.github.com>
|
||||
- chanduthedev <chanduthedev@gmail.com>
|
||||
- czephyr <alfredo.funicello@studenti.unimi.it>
|
||||
- damencho <damencho@jitsi.org>
|
||||
- ddeka2910 <60925700+ddeka2910@users.noreply.github.com>
|
||||
- dominiquefournier <dominique@fournier38.fr>
|
||||
- eakraly <eakraly@users.noreply.github.com>
|
||||
- ggalperi <81175455+ggalperi@users.noreply.github.com>
|
||||
- hariprasadt <hariprasad.t@samsung.com>
|
||||
- huhaipeng <huhaipeng@corp.netease.com>
|
||||
- islamoglus <islamogluselahaddin@gmail.com>
|
||||
- korayvt <korayvt@users.noreply.github.com>
|
||||
- maddy <maddy@kitty.garden>
|
||||
- marcoschum <50410120+marcoschum@users.noreply.github.com>
|
||||
- misi <bakfitty@gmail.com>
|
||||
- mom040267 <mom040267@gmail.com>
|
||||
@ -132,13 +161,16 @@ Thanks to the following contributors (in alphabetical order):
|
||||
- ooookai <ooookai@users.noreply.github.com>
|
||||
- r3g_5z <june@girlboss.ceo>
|
||||
- raghumuppa <mupparthies@gmail.com>
|
||||
- redraincatching <99604494+redraincatching@users.noreply.github.com>
|
||||
- release-it <release-it@tawenda.com>
|
||||
- rim <11380091+rozhuk-im@users.noreply.github.com>
|
||||
- root <root@centot7.test.in.securom.me>
|
||||
- seungbin-ko <seungbin.ko@navercorp.com>
|
||||
- shuyin.wsy <shuyin.wsy@alibaba-inc.com>
|
||||
- skystar-p <wogus150@naver.com>
|
||||
- tyranron <tyranron@gmail.com>
|
||||
- unicode-it <info@unicode-it.de>
|
||||
- vuittont60 <81072379+vuittont60@users.noreply.github.com>
|
||||
- wolmi <lenyos@gmail.com>
|
||||
- xthursdayx <xthursdayx@mailbox.org>
|
||||
- yohan <783b8c87@scimetis.net>
|
||||
|
||||
@ -9,9 +9,7 @@ set(CMAKE_C_STANDARD_REQUIRED ON)
|
||||
|
||||
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/cmake)
|
||||
# TODO: Modify this when the version is released
|
||||
SET(BUILD_VERSION "4.6.2")
|
||||
|
||||
option(FUZZER "Build oss-fuzz fuzzing" OFF)
|
||||
SET(BUILD_VERSION "4.6.3")
|
||||
|
||||
# Find Git Version Patch
|
||||
IF(EXISTS "${CMAKE_SOURCE_DIR}/.git")
|
||||
@ -137,6 +135,7 @@ install(DIRECTORY
|
||||
)
|
||||
include(cmake/CMakeCPack.cmake)
|
||||
|
||||
option(FUZZER "Build oss-fuzz fuzzing" OFF)
|
||||
if(FUZZER)
|
||||
if (NOT CMAKE_C_COMPILER_ID STREQUAL "Clang")
|
||||
message(FATAL_ERROR "clang is require for libFuzzer")
|
||||
|
||||
152
ChangeLog
152
ChangeLog
@ -1,3 +1,155 @@
|
||||
Release 4.6.3
|
||||
|
||||
Changelist:
|
||||
- Implement custom prometheus http handler (#1591) (Alex Gustafsson <89969483+alexg-axis@users.noreply.github.com>)
|
||||
- Add MariaDB support to README.md (#1601) (Robert Silén <robert.silen@mariadb.org>)
|
||||
- Allow authenticating with a username to redis (#1488) (maddy <maddy@kitty.garden>)
|
||||
- Easy installation of coturn on AWS (#1581) (hariprasadt <hariprasad.t@samsung.com>)
|
||||
- Add prometheus setting suggestions on turn.conf in example folder (#1597) (Chai-Shi <changchaishi@gmail.com>)
|
||||
- Install openssl-1.1.1 on amazonlinux:2 instead of openssl-1.0.1 (#1595) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Add new Drain feature (#1529) (Scott Godin <sgodin@sipspectrum.com>)
|
||||
- Additional refactoring of ns_turn_allocation.* to address security scanner concerns (#1514) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix linting error in mainrelay.c (#1558) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Fix rpm version scripts (#1556) (eakraly <eakraly@users.noreply.github.com>)
|
||||
- Delete dead code (#1563) (Sven Tennie <sven.tennie@gmail.com>)
|
||||
- Fix cli auth (#1578) (Mészáros Mihály <misi@majd.eu>)
|
||||
- Use bool, instead of int, for the functions in ns_turn_msg.c (#1553) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Reformat code (#1557) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- configure: data files shouldn't be executable (#1542) (Sergey Radionov <RSATom@gmail.com>)
|
||||
- Update libtelnet (#1545) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Use calloc where appropriate, avoid memset when normal buffer initialization works (#1550) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix make lint (#1547) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix compiler warnings from continuous integration (#1555) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix nodejs/glibc problem with old container images. (#1548) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Windows: Only attempt to bind when the network interface is up (#1527) (David Smitmanis <davidsm@axis.com>)
|
||||
- Memset user_db before reading conf file, not after (#1537) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- added support for amazon linux and renamed tests.yml (#1401) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Check the result of malloc in send_message_to_redis (#1515) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Check the result of malloc in mongo_set_realm_option_one (#1516) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Simplify workflow for codeql (#1517) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Move the hiredis_libevent2 code from common to relay (#1509) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Include what you use (#1512) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Check the result of malloc in string_list_add (#1495) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Check the result of realloc and calloc in ch_map_get (#1497) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Address clang-tidy warnings in db files (#1405) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- malloc now allocates space for string terminator (#1507) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Use bool over int for the turnutils_uclient program (#1420) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix lint complaint about comment (#1506) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Run all of the CI except for Docker builds on any change (#1415) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Avoid read-past-end of string in get_bold_admin_title (#1499) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Check allocation results in add_static_user_account (#1501) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Address some build issues introduced by api changes (#1505) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Check the result of calloc in handle_logon_request (#1498) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Avoid writing potentially uninitialized data to aes_128 key file (#1500) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Use active CPU number instead of total number (#1469) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- defined a magic number for stun fingerprinting (#1489) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Always run lint, regardless of branch (#1492) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- avoid potential nullptr derefernence in udp_create_server_socket (#1496) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Change the various map functions to return bool instead of inconsistantly return 0, 1, or -1 (#1502) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Check the result of malloc in del_alt_server (#1503) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Avoid nullptr dereference of server variable in various functions (#1504) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Fix msvc analyzer error on goto label on rfc5769check (#1486) (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Fix buffer overflow in generate_enc_password with increase rsalt by 2 (#1463) (Stefan Junker <1181362+steveej@users.noreply.github.com>)
|
||||
- Fix lint errors (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Add support for raw public keys (Rfc 7250) (#1458) (Nikolayshcx <77790944+Nikolayshcx@users.noreply.github.com>)
|
||||
- Fix clang-format lint warnings (Gustavo Garcia <gustavogb@mail.com>)
|
||||
- Fix const during free warning in rfc5769check app (Gustavo Garcia <gustavogb@mail.com>)
|
||||
- Refactor: peer_input_handle (#1325) (Kang Lin <kl222@126.com>)
|
||||
- workflow tidying (#1396) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Update turnserver.conf Example about listening-ip (#1336) (Wittmer, Christian <chris@computersalat.de>)
|
||||
- Fix Cmake find issue in libevent (#1466) (NO NAME <45446340+linwenchen@users.noreply.github.com>)
|
||||
- CMake: Declare the variable nearby (#1387) (Kang Lin <kl222@126.com>)
|
||||
- Print version only, no extra lines (#1441) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Fix memory leak in rfc5769check.c (#1410) (ashamedbit <muralianiruddhan@gmail.com>)
|
||||
- Fix memory leak in netengine.c (#1411) (ashamedbit <muralianiruddhan@gmail.com>)
|
||||
- Fix memory leak on http_server.c (#1412) (ashamedbit <muralianiruddhan@gmail.com>)
|
||||
- ubuntu build dependencies extracted to composite actions (#1399) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Delete unused variable (#1437) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- changed variables in stunclient.c to bool (C11) (#1421) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- added missing function prototype of turn_random_number() (#1428) (redraincatching <99604494+redraincatching@users.noreply.github.com>)
|
||||
- Fix no-tls warning typo (#1426) (Jan Brasna <1784648+janbrasna@users.noreply.github.com>)
|
||||
- Update SQLite.md (#1429) (dominiquefournier <dominique@fournier38.fr>)
|
||||
- Adjust wording in cmake message when prometheous cannot be found. (#1418) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Add the InsertBraces command for clang-format to ensure that all conditionals always have braces (#1408) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Change minimal required cmake version to 3.16 (#1388) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Replace HeapAlloc with malloc (#1378) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Added sessionID to some log lines (#1334) (korayvt <korayvt@users.noreply.github.com>)
|
||||
- Update FlowChart (#1377) (Kang Lin <kl222@126.com>)
|
||||
- Add clang-tidy, include-what-you-use, and msvc-analyzer github actions (#1363) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Doc: add flowchart (#1328) (Kang Lin <kl222@126.com>)
|
||||
- Missing session ID in coturn logs for denied IP - 1330 (#1332) (Cybermilitia <Cybermilitia@users.noreply.github.com>)
|
||||
- Update lukka/run-vcpkg@11 (#1374) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Fix typos (#1345) (vuittont60 <81072379+vuittont60@users.noreply.github.com>)
|
||||
- Fix mingw build (#1376) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Add github action that runs tests with compiler sanitizers (#1370) (Michael Jones <jonesmz@users.noreply.github.com>)
|
||||
- Simplify macOS detection macros (#1372) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Fix potential null passed to function expecting nonnull (#1373) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Only set MHD_USE_DUAL_STACK if IPv6 is available (#1362) (Evgeny Khramtsov <xramtsov@gmail.com>)
|
||||
- Remove unimplemented test folder reference from CMakeLists.txt (#1371) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Fix cmake find prometheus(fix #1304) (#1315) (Kang Lin <kl222@126.com>)
|
||||
- Fix run cmake.yml in any github action (#1320) (Kang Lin <kl222@126.com>)
|
||||
- Fix return correct error code for `create_relay_connection` in case of `RESERVATION-TOKEN` failure (#1319) (Subhra264 <chakrabortysubhradeep556@gmail.com>)
|
||||
- Reduce ifdefs in code: TURN_NO_PROMETHEUS (#1116) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- strncpy doesn't return size_t (#1296) (Richard Russo <richard@signal.org>)
|
||||
- Return a 400 response to HTTP requests (#1231) (Dave Lambley <dave@lambley.me.uk>)
|
||||
- Fix missing strncpy in fix_stun_check_message_integrity_str (#1282) (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Fix ubuntu 16 build with GH action checkout version to v3 (#1281) (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Fix memleak in pgsql_reread_realms (#1278) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- Replace srand/rand with srandom/random (#1279) (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Fix memcpy len checks stun_is_challenge_response_str (#1280) (Gustavo Garcia <gustavogb@gmail.com>)
|
||||
- Add warning and disable web admin if no-tls option used (#1256) (Alexander Udovichenko <udovichenko48@gmail.com>)
|
||||
- Fix formatting to fix lint error (#1258) (Pavel Punsky <eakraly@users.noreply.github.com>)
|
||||
- added warnings for prometheus apt unavailability (#1184) (czephyr <alfredo.funicello@studenti.unimi.it>)
|
||||
- Update version in vcpkg.json (#1254) (Kang Lin <kl222@126.com>)
|
||||
- Fix error of make command in Cygwin environment (#1236) (Aaron Bird <25508292+Aaron-Bird@users.noreply.github.com>)
|
||||
- Fix recursive call in delete alternate server (#1250) (Cybermilitia <Cybermilitia@users.noreply.github.com>)
|
||||
- Add CodeQL workflow (#1228) (Jorge <46056498+jorgectf@users.noreply.github.com>)
|
||||
- Change printf() to TURN_LOG_FUNC() for --no-stdout-log (#1221) (Robert Scheck <robert-scheck@users.noreply.github.com>)
|
||||
- Fix build with libressl 3.6+ (#1198) (rim <11380091+rozhuk-im@users.noreply.github.com>)
|
||||
- Update turnserver.spec (#1192) (Mathieu Aubin <mathieu@zeroserieux.com>)
|
||||
|
||||
Contributors:
|
||||
- Aaron Bird <25508292+Aaron-Bird@users.noreply.github.com>
|
||||
- Alex Gustafsson <89969483+alexg-axis@users.noreply.github.com>
|
||||
- Alexander Udovichenko <udovichenko48@gmail.com>
|
||||
- Chai-Shi <changchaishi@gmail.com>
|
||||
- Cybermilitia <Cybermilitia@users.noreply.github.com>
|
||||
- Dave Lambley <dave@lambley.me.uk>
|
||||
- David Smitmanis <davidsm@axis.com>
|
||||
- Evgeny Khramtsov <xramtsov@gmail.com>
|
||||
- Gustavo Garcia <gustavogb@gmail.com>
|
||||
- Gustavo Garcia <gustavogb@mail.com>
|
||||
- Jan Brasna <1784648+janbrasna@users.noreply.github.com>
|
||||
- Jorge <46056498+jorgectf@users.noreply.github.com>
|
||||
- Kang Lin <kl222@126.com>
|
||||
- Mathieu Aubin <mathieu@zeroserieux.com>
|
||||
- Mészáros Mihály <misi@majd.eu>
|
||||
- Michael Jones <jonesmz@users.noreply.github.com>
|
||||
- NO NAME <45446340+linwenchen@users.noreply.github.com>
|
||||
- Nikolayshcx <77790944+Nikolayshcx@users.noreply.github.com>
|
||||
- Pavel Punsky <eakraly@users.noreply.github.com>
|
||||
- Richard Russo <richard@signal.org>
|
||||
- Robert Scheck <robert-scheck@users.noreply.github.com>
|
||||
- Robert Silén <robert.silen@mariadb.org>
|
||||
- Scott Godin <sgodin@sipspectrum.com>
|
||||
- Sergey Radionov <RSATom@gmail.com>
|
||||
- Stefan Junker <1181362+steveej@users.noreply.github.com>
|
||||
- Subhra264 <chakrabortysubhradeep556@gmail.com>
|
||||
- Sven Tennie <sven.tennie@gmail.com>
|
||||
- Wittmer, Christian <chris@computersalat.de>
|
||||
- Zoey <zoey@z0ey.de>
|
||||
- ashamedbit <muralianiruddhan@gmail.com>
|
||||
- czephyr <alfredo.funicello@studenti.unimi.it>
|
||||
- dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
|
||||
- dominiquefournier <dominique@fournier38.fr>
|
||||
- eakraly <eakraly@users.noreply.github.com>
|
||||
- hariprasadt <hariprasad.t@samsung.com>
|
||||
- korayvt <korayvt@users.noreply.github.com>
|
||||
- maddy <maddy@kitty.garden>
|
||||
- redraincatching <99604494+redraincatching@users.noreply.github.com>
|
||||
- rim <11380091+rozhuk-im@users.noreply.github.com>
|
||||
- vuittont60 <81072379+vuittont60@users.noreply.github.com>
|
||||
|
||||
Release 4.6.2
|
||||
|
||||
Changelist:
|
||||
|
||||
30
Makefile.in
30
Makefile.in
@ -1,19 +1,19 @@
|
||||
|
||||
LIBEVENT_INCLUDE = -I${PREFIX}/include/ -I/usr/local/include/
|
||||
|
||||
INCFLAGS = -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ ${LIBEVENT_INCLUDE}
|
||||
INCFLAGS = -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ ${LIBEVENT_INCLUDE}
|
||||
|
||||
CFLAGS += ${INCFLAGS}
|
||||
|
||||
MAKE_DEPS = Makefile
|
||||
|
||||
LIBCLIENTTURN_HEADERS = src/ns_turn_defs.h src/client++/TurnMsgLib.h src/client/ns_turn_ioaddr.h src/client/ns_turn_msg.h src/client/ns_turn_msg_defs.h src/client/ns_turn_msg_defs_experimental.h src/client/ns_turn_msg_addr.h
|
||||
LIBCLIENTTURN_MODS = src/client/ns_turn_ioaddr.c src/client/ns_turn_msg_addr.c src/client/ns_turn_msg.c
|
||||
LIBCLIENTTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${MAKE_DEPS}
|
||||
LIBCLIENTTURN_OBJS = build/obj/ns_turn_ioaddr.o build/obj/ns_turn_msg_addr.o build/obj/ns_turn_msg.o
|
||||
LIBCLIENTTURN_MODS = src/client/ns_turn_ioaddr.c src/client/ns_turn_msg_addr.c src/client/ns_turn_msg.c
|
||||
LIBCLIENTTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${MAKE_DEPS}
|
||||
LIBCLIENTTURN_OBJS = build/obj/ns_turn_ioaddr.o build/obj/ns_turn_msg_addr.o build/obj/ns_turn_msg.o
|
||||
|
||||
SERVERTURN_HEADERS = src/server/ns_turn_allocation.h src/server/ns_turn_ioalib.h src/server/ns_turn_khash.h src/server/ns_turn_maps_rtcp.h src/server/ns_turn_maps.h src/server/ns_turn_server.h src/server/ns_turn_session.h
|
||||
SERVERTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${SERVERTURN_HEADERS} ${MAKE_DEPS}
|
||||
SERVERTURN_DEPS = ${LIBCLIENTTURN_HEADERS} ${SERVERTURN_HEADERS} ${MAKE_DEPS}
|
||||
SERVERTURN_MODS = ${LIBCLIENTTURN_MODS} src/server/ns_turn_allocation.c src/server/ns_turn_maps_rtcp.c src/server/ns_turn_maps.c src/server/ns_turn_server.c
|
||||
|
||||
COMMON_HEADERS = src/apps/common/apputils.h src/apps/common/ns_turn_openssl.h src/apps/common/ns_turn_utils.h src/apps/common/stun_buffer.h
|
||||
@ -24,8 +24,8 @@ IMPL_HEADERS = src/apps/relay/ns_ioalib_impl.h src/apps/relay/ns_sm.h src/apps/r
|
||||
IMPL_MODS = src/apps/relay/ns_ioalib_engine_impl.c src/apps/relay/turn_ports.c src/apps/relay/http_server.c src/apps/relay/acme.c
|
||||
IMPL_DEPS = ${COMMON_DEPS} ${IMPL_HEADERS} ${IMPL_MODS}
|
||||
|
||||
HIREDIS_HEADERS = src/apps/common/hiredis_libevent2.h
|
||||
HIREDIS_MODS = src/apps/common/hiredis_libevent2.c
|
||||
HIREDIS_HEADERS = src/apps/relay/hiredis_libevent2.h
|
||||
HIREDIS_MODS = src/apps/relay/hiredis_libevent2.c
|
||||
|
||||
USERDB_HEADERS = src/apps/relay/dbdrivers/dbdriver.h src/apps/relay/dbdrivers/dbd_sqlite.h src/apps/relay/dbdrivers/dbd_pgsql.h src/apps/relay/dbdrivers/dbd_mysql.h src/apps/relay/dbdrivers/dbd_mongo.h src/apps/relay/dbdrivers/dbd_redis.h
|
||||
USERDB_MODS = src/apps/relay/dbdrivers/dbdriver.c src/apps/relay/dbdrivers/dbd_sqlite.c src/apps/relay/dbdrivers/dbd_pgsql.c src/apps/relay/dbdrivers/dbd_mysql.c src/apps/relay/dbdrivers/dbd_mongo.c src/apps/relay/dbdrivers/dbd_redis.c
|
||||
@ -60,7 +60,7 @@ include/turn/ns_turn_defs.h: src/ns_turn_defs.h
|
||||
|
||||
bin/turnutils_uclient: ${COMMON_DEPS} src/apps/uclient/session.h lib/libturnclient.a src/apps/uclient/mainuclient.c src/apps/uclient/uclient.c src/apps/uclient/uclient.h src/apps/uclient/startuclient.c src/apps/uclient/startuclient.h
|
||||
${MKBUILDDIR} bin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/uclient/uclient.c src/apps/uclient/startuclient.c src/apps/uclient/mainuclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/uclient/uclient.c src/apps/uclient/startuclient.c src/apps/uclient/mainuclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
|
||||
bin/turnutils_natdiscovery: ${COMMON_DEPS} lib/libturnclient.a src/apps/natdiscovery/natdiscovery.c
|
||||
pwd
|
||||
@ -72,21 +72,21 @@ bin/turnutils_oauth: ${COMMON_DEPS} lib/libturnclient.a src/apps/oauth/oauth.c
|
||||
${MKBUILDDIR} bin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/oauth/oauth.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
|
||||
bin/turnutils_stunclient: ${COMMON_DEPS} lib/libturnclient.a src/apps/stunclient/stunclient.c
|
||||
bin/turnutils_stunclient: ${COMMON_DEPS} lib/libturnclient.a src/apps/stunclient/stunclient.c
|
||||
pwd
|
||||
${MKBUILDDIR} bin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/stunclient/stunclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/stunclient/stunclient.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
|
||||
bin/turnutils_rfc5769check: ${COMMON_DEPS} lib/libturnclient.a src/apps/rfc5769/rfc5769check.c
|
||||
bin/turnutils_rfc5769check: ${COMMON_DEPS} lib/libturnclient.a src/apps/rfc5769/rfc5769check.c
|
||||
pwd
|
||||
${MKBUILDDIR} bin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/rfc5769/rfc5769check.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} src/apps/rfc5769/rfc5769check.c ${COMMON_MODS} -o $@ -Llib -lturnclient -Llib ${LDFLAGS}
|
||||
|
||||
bin/turnserver: ${SERVERAPP_DEPS}
|
||||
${MKBUILDDIR} bin
|
||||
${RMCMD} bin/turnadmin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} ${DBCFLAGS} ${IMPL_MODS} -Ilib ${SERVERAPP_MODS} ${COMMON_MODS} ${SERVERTURN_MODS} -o $@ ${DBLIBS} ${LDFLAGS}
|
||||
cd bin; ln -s turnserver turnadmin
|
||||
${CC} ${CPPFLAGS} ${CFLAGS} ${DBCFLAGS} ${IMPL_MODS} -Ilib ${SERVERAPP_MODS} ${COMMON_MODS} ${SERVERTURN_MODS} -o $@ ${DBLIBS} ${LDFLAGS}
|
||||
cd bin; ln -s turnserver turnadmin
|
||||
|
||||
bin/turnutils_peer: ${COMMON_DEPS} ${LIBCLIENTTURN_MODS} ${LIBCLIENTTURN_DEPS} lib/libturnclient.a src/apps/peer/mainudpserver.c src/apps/peer/udpserver.h src/apps/peer/udpserver.c
|
||||
${MKBUILDDIR} bin
|
||||
@ -112,7 +112,7 @@ build/obj/ns_turn_msg.o: src/client/ns_turn_msg.c ${LIBCLIENTTURN_DEPS}
|
||||
|
||||
### Clean all:
|
||||
|
||||
clean:
|
||||
clean:
|
||||
${RMCMD} bin build lib obj *bak *~ */*~ */*/*~ */*/*/*~ *core */*core */*/*core include tmp sqlite
|
||||
|
||||
distclean: clean
|
||||
|
||||
@ -35,7 +35,7 @@ coturn requires following dependencies to be installed first
|
||||
Optional
|
||||
- openssl (to support TLS and DTLS, authorized STUN and TURN)
|
||||
- libmicrohttp and [prometheus-client-c](https://github.com/digitalocean/prometheus-client-c) (prometheus interface)
|
||||
- MySQL (user database)
|
||||
- MariaDB/MySQL (user database)
|
||||
- [Hiredis](https://github.com/redis/hiredis) (user database, monitoring)
|
||||
- SQLite (user database)
|
||||
- PostgreSQL (user database)
|
||||
@ -98,7 +98,7 @@ Relay protocols:
|
||||
User databases (for user repository, with passwords or keys, if authentication is required):
|
||||
|
||||
* SQLite
|
||||
* MySQL
|
||||
* MariaDB/MySQL
|
||||
* PostgreSQL
|
||||
* Redis
|
||||
* MongoDB
|
||||
|
||||
@ -168,7 +168,10 @@ Flags:
|
||||
|
||||
-o, --daemon Run server as daemon.
|
||||
|
||||
--no-software-attribute Production mode: hide the software version.
|
||||
--no-software-attribute DEPRECATED. See "--software-attribute".
|
||||
|
||||
--software-attribute Send SOFTWARE_ATTRIBUTE on messages that can have it. Disabled by default.
|
||||
Equals to deprecated option "--no-software-attribute false".
|
||||
|
||||
-f, --fingerprint Use fingerprints in the TURN messages. If an incoming request
|
||||
contains a fingerprint, then TURN server will always add
|
||||
@ -483,6 +486,10 @@ Options with values:
|
||||
are specified, then this parameter is not needed.
|
||||
Default value is turn_server_pkey.pem.
|
||||
|
||||
--raw-public-keys Raw public keys support.
|
||||
On/off switch for RFC-7250 aka raw public keys.
|
||||
Coturn must be built against openSSL version at least 3.2.1
|
||||
|
||||
--pkey-pwd If the private key file is encrypted, then this password to be used.
|
||||
|
||||
--cipher-list Allowed OpenSSL cipher list for TLS/DTLS connections.
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
#
|
||||
# Try to find prometheus
|
||||
# Once done, this will define:
|
||||
# Prometheus_FOUND - Prometheus (or all requested components of prom, promhttp, microhttpd) was found.
|
||||
# Prometheus_FOUND - Prometheus (or all requested components of prom, microhttpd) was found.
|
||||
# Prometheus_INCLUDE_DIRS - Libevent include directories
|
||||
# Prometheus_LIBRARIES - libraries needed to use Prometheus
|
||||
#
|
||||
@ -16,9 +16,8 @@ include(FindPackageHandleStandardArgs)
|
||||
|
||||
find_package(PkgConfig)
|
||||
pkg_check_modules(PC_prom QUIET prom)
|
||||
pkg_check_modules(PC_promhttp QUIET promhttp)
|
||||
pkg_check_modules(PC_microhttd QUIET microhttpd)
|
||||
|
||||
|
||||
find_path(microhttpd_include_dir
|
||||
NAMES microhttpd.h
|
||||
HINTS ${Prometheus_DIR} ${Prometheus_ROOT} ${PC_microhttd_INCLUDE_DIRS} /usr
|
||||
@ -47,28 +46,12 @@ find_library(
|
||||
PATHS $ENV{Prometheus_DIR} $ENV{Prometheus_ROOT}
|
||||
PATH_SUFFIXES lib ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
find_path(promhttp_INCLUDE_DIR
|
||||
NAMES promhttp.h
|
||||
HINTS ${Prometheus_DIR} ${Prometheus_ROOT} ${PC_promhttp_INCLUDE_DIRS} /usr
|
||||
PATHS $ENV{Prometheus_DIR} $ENV{Prometheus_ROOT}
|
||||
PATH_SUFFIXES include
|
||||
)
|
||||
|
||||
find_library(
|
||||
promhttp_libs
|
||||
NAMES promhttp
|
||||
HINTS ${Prometheus_DIR} ${Prometheus_ROOT} ${PC_promhttp_LIBRARY_DIRS}
|
||||
PATHS $ENV{Prometheus_DIR} $ENV{Prometheus_ROOT}
|
||||
PATH_SUFFIXES lib ${CMAKE_INSTALL_LIBDIR})
|
||||
|
||||
find_package_handle_standard_args(Prometheus
|
||||
REQUIRED_VARS prom_libs prom_INCLUDE_DIR
|
||||
promhttp_libs promhttp_INCLUDE_DIR
|
||||
microhttpd_include_dir microhttpd_libs
|
||||
)
|
||||
|
||||
set(Prometheus_INCLUDE_DIRS
|
||||
${prom_INCLUDE_DIR}
|
||||
${promhttp_INCLUDE_DIR}
|
||||
${microhttpd_include_dir})
|
||||
set(Prometheus_LIBRARIES ${prom_libs} ${promhttp_libs} ${microhttpd_libs})
|
||||
set(Prometheus_LIBRARIES ${prom_libs} ${microhttpd_libs})
|
||||
|
||||
28
configure
vendored
28
configure
vendored
@ -466,7 +466,7 @@ else
|
||||
INSTALL_SCRIPT="install -p"
|
||||
INSTALL_SHARED_LIB="install -p"
|
||||
INSTALL_STATIC_LIB="install -p"
|
||||
INSTALL_DATA="install -p"
|
||||
INSTALL_DATA="install -p -m 0644"
|
||||
MKDIR="install -d"
|
||||
else
|
||||
INSTALL_PROGRAM="cp -pf"
|
||||
@ -848,30 +848,18 @@ if [ -z "${TURN_NO_PROMETHEUS}" ] ; then
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "Prometheus lib found."
|
||||
testlib promhttp
|
||||
testlib microhttpd
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "Prometheus http lib found."
|
||||
testlib microhttpd
|
||||
ER=$?
|
||||
if ! [ ${ER} -eq 0 ] ; then
|
||||
${ECHO_CMD} "Microhttpd lib found."
|
||||
# Adjustments for Debian
|
||||
# See: https://github.com/coturn/coturn/pull/754#issuecomment-824693226
|
||||
if [ -f "/etc/debian_version" ] ; then
|
||||
OSLIBS="${OSLIBS} -latomic"
|
||||
fi
|
||||
else
|
||||
${ECHO_CMD}
|
||||
${ECHO_CMD} "Warning: microhttpd development libraries are not installed properly in required location."
|
||||
${ECHO_CMD} "Prometheus support will be disabled."
|
||||
${ECHO_CMD} "See the docs/Prometheus.md file."
|
||||
${ECHO_CMD}
|
||||
OSCFLAGS="${OSCFLAGS} -DTURN_NO_PROMETHEUS"
|
||||
${ECHO_CMD} "Microhttpd lib found."
|
||||
# Adjustments for Debian
|
||||
# See: https://github.com/coturn/coturn/pull/754#issuecomment-824693226
|
||||
if [ -f "/etc/debian_version" ] ; then
|
||||
OSLIBS="${OSLIBS} -latomic"
|
||||
fi
|
||||
else
|
||||
${ECHO_CMD}
|
||||
${ECHO_CMD} "Warning: Libpromhttp development libraries are not installed properly in required location."
|
||||
${ECHO_CMD} "Warning: microhttpd development libraries are not installed properly in required location."
|
||||
${ECHO_CMD} "Prometheus support will be disabled."
|
||||
${ECHO_CMD} "See the docs/Prometheus.md file."
|
||||
${ECHO_CMD}
|
||||
|
||||
@ -4,11 +4,94 @@ Coturn TURN server Docker image changelog
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r7] · 202?-??-?? (unreleased)
|
||||
[4.6.2-r7]: /../../tree/docker/4.6.2-r7
|
||||
## [4.6.3-r1] · 2025-01-08
|
||||
[4.6.3-r1]: /../../tree/docker/4.6.3-r1
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Alpine Linux] 3.21.1: <https://github.com/docker-library/official-images/commit/34b47f1f4bdef69e39ae335e55b0f07af3b4fa18>
|
||||
- [Debian Linux] "bookworm" 20241223 (12.8): <https://github.com/docker-library/official-images/commit/b6ea0fc48d92a7f6ef631667e82600666be53181>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.3-r0] · 2024-12-11
|
||||
[4.6.3-r0]: /../../tree/docker/4.6.3-r0
|
||||
|
||||
### Upgraded
|
||||
|
||||
- [Coturn] 4.6.3: <https://github.com/coturn/coturn/blob/4.6.3/ChangeLog>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r13] · 2024-12-06
|
||||
[4.6.2-r13]: /../../tree/docker/4.6.2-r13
|
||||
|
||||
### Upgraded
|
||||
|
||||
- [Alpine Linux] 3.21: <https://alpinelinux.org/posts/Alpine-3.21.0-released.html>
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Debian Linux] "bookworm" 20241202 (12.8): <https://github.com/docker-library/official-images/commit/36ffb3d236c35c22922dfeca1844d7ad119b06f5>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r12] · 2024-09-09
|
||||
[4.6.2-r12]: /../../tree/docker/4.6.2-r12
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Alpine Linux] 3.20.3: <https://github.com/docker-library/official-images/commit/94a433c3550a63993b4d7a2081ae87dfe1f7f6bf>
|
||||
- [Debian Linux] "bookworm" 20240904 (12.7): <https://github.com/docker-library/official-images/commit/c8fa319f742b43465f60dda8d67cdc8d66eb615d>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r11] · 2024-07-26
|
||||
[4.6.2-r11]: /../../tree/docker/4.6.2-r11
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Alpine Linux] 3.20.2: <https://github.com/docker-library/official-images/commit/1a994d381a873e6f9579843dd1eebf64bc50e831>
|
||||
- [Debian Linux] "bookworm" 20240722 (12.6): <https://github.com/docker-library/official-images/commit/62a03fd2a8fd79c245b11fb01e3e9d1be4214566>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r10] · 2024-06-21
|
||||
[4.6.2-r10]: /../../tree/docker/4.6.2-r10
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Alpine Linux] 3.20.1: <https://github.com/docker-library/official-images/commit/9434c6383adc38dd26c6c1b098bed1981a6d9e7f>
|
||||
- [Debian Linux] "bookworm" 20240612 (12.5): <https://github.com/docker-library/official-images/commit/5891883bb94aefbf0ec4fa1fea1bc4679d164657>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r9] · 2024-05-24
|
||||
[4.6.2-r9]: /../../tree/docker/4.6.2-r9
|
||||
|
||||
### Upgraded
|
||||
|
||||
- [Alpine Linux] 3.20: <https://alpinelinux.org/posts/Alpine-3.20.0-released.html>
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Debian Linux] "bookworm" 20240513 (12.5): <https://github.com/docker-library/official-images/commit/d83cd3afd0e94fbf9a7ef07bdc84ac2b4a492e91>
|
||||
|
||||
|
||||
|
||||
|
||||
## [4.6.2-r8] · 2024-01-29
|
||||
[4.6.2-r8]: /../../tree/docker/4.6.2-r8
|
||||
|
||||
### Security updated
|
||||
|
||||
- [Alpine Linux] 3.19.1: <https://github.com/docker-library/official-images/commit/a5a02e00e489cfaa9dc8056755cd00abe7d0f646>
|
||||
- [Debian Linux] "bookworm" 20240110 (12.4): <https://github.com/docker-library/official-images/commit/06237a1cf18ad130b442a864854804c1a534ff29>
|
||||
|
||||
|
||||
|
||||
@ -24,7 +24,7 @@ dockerify = $(strip $(if $(call eq,$(1),linux/arm32v6),linux/arm/v6,\
|
||||
# Project parameters #
|
||||
######################
|
||||
|
||||
COTURN_VER ?= 4.6.2
|
||||
COTURN_VER ?= 4.6.3
|
||||
COTURN_MIN_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1,2))
|
||||
COTURN_MAJ_VER = $(strip $(shell echo $(COTURN_VER) | cut -d '.' -f1))
|
||||
|
||||
@ -34,7 +34,7 @@ ALPINE_VER := alpine$(strip $(shell grep -m1 'alpine_ver=' alpine/Dockerfile \
|
||||
DEBIAN_VER := $(strip $(shell grep -m1 'debian_ver=' debian/Dockerfile \
|
||||
| cut -d '=' -f2))
|
||||
|
||||
BUILD_REV ?= 7
|
||||
BUILD_REV ?= 1
|
||||
|
||||
NAME := coturn
|
||||
OWNER := $(or $(GITHUB_REPOSITORY_OWNER),coturn)
|
||||
|
||||
@ -15,8 +15,8 @@ Coturn TURN server Docker image
|
||||
|
||||
## Supported tags and respective `Dockerfile` links
|
||||
|
||||
- [`4.6.2-r7`, `4.6.2-r7-debian`, `4.6.2`, `4.6.2-debian`, `4.6.2-bookworm`, `4.6`, `4.6-debian`, `4.6-bookworm`, `4`, `4-debian`, `4-bookworm`, `debian`, `bookworm`, `latest`][d1]
|
||||
- [`4.6.2-r7-alpine`, `4.6.2-alpine`, `4.6.2-alpine3.19`, `4.6-alpine`, `4.6-alpine3.19`, `4-alpine`, `4-alpine3.19`, `alpine`, `alpine3.19`][d2]
|
||||
- [`4.6.3-r1`, `4.6.3-r1-debian`, `4.6.3`, `4.6.3-debian`, `4.6.3-bookworm`, `4.6`, `4.6-debian`, `4.6-bookworm`, `4`, `4-debian`, `4-bookworm`, `debian`, `bookworm`, `latest`][d1]
|
||||
- [`4.6.3-r1-alpine`, `4.6.3-alpine`, `4.6.3-alpine3.21`, `4.6-alpine`, `4.6-alpine3.21`, `4-alpine`, `4-alpine3.21`, `alpine`, `alpine3.21`][d2]
|
||||
|
||||
|
||||
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
# Dockerfile of coturn/coturn:alpine Docker image.
|
||||
#
|
||||
|
||||
ARG alpine_ver=3.19
|
||||
ARG alpine_ver=3.21
|
||||
|
||||
|
||||
|
||||
@ -46,27 +46,13 @@ RUN mkdir -p /build/prom/build/ && cd /build/prom/build/ \
|
||||
.. \
|
||||
&& make
|
||||
|
||||
# Build libpromhttp.so from sources.
|
||||
RUN mkdir -p /build/promhttp/build/ && cd /build/promhttp/build/ \
|
||||
# Fix compiler warning: -Werror=incompatible-pointer-types
|
||||
&& sed -i 's/\&promhttp_handler/(MHD_AccessHandlerCallback)\&promhttp_handler/' \
|
||||
/build/promhttp/src/promhttp.c \
|
||||
&& TEST=0 cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_SKIP_BUILD_RPATH=TRUE \
|
||||
-DCMAKE_C_FLAGS="-g -O3" \
|
||||
.. \
|
||||
&& make VERBOSE=1
|
||||
|
||||
# Install prometheus-client-c.
|
||||
RUN LIBS_DIR=/out/$(dirname $(find /usr/ -name libc.so)) \
|
||||
&& mkdir -p $LIBS_DIR/ \
|
||||
&& cp -rf /build/prom/build/libprom.so \
|
||||
/build/promhttp/build/libpromhttp.so \
|
||||
$LIBS_DIR/ \
|
||||
&& mkdir -p /out/usr/include/ \
|
||||
&& cp -rf /build/prom/include/* \
|
||||
/build/promhttp/include/* \
|
||||
/out/usr/include/ \
|
||||
# Preserve license file.
|
||||
&& mkdir -p /out/usr/share/licenses/prometheus-client-c/ \
|
||||
|
||||
@ -46,27 +46,13 @@ RUN mkdir -p /build/prom/build/ && cd /build/prom/build/ \
|
||||
.. \
|
||||
&& make
|
||||
|
||||
# Build libpromhttp.so from sources.
|
||||
RUN mkdir -p /build/promhttp/build/ && cd /build/promhttp/build/ \
|
||||
# Fix compiler warning: -Werror=incompatible-pointer-types
|
||||
&& sed -i 's/\&promhttp_handler/(MHD_AccessHandlerCallback)\&promhttp_handler/' \
|
||||
/build/promhttp/src/promhttp.c \
|
||||
&& TEST=0 cmake -G "Unix Makefiles" \
|
||||
-DCMAKE_INSTALL_PREFIX=/usr \
|
||||
-DCMAKE_SKIP_BUILD_RPATH=TRUE \
|
||||
-DCMAKE_C_FLAGS="-g -O3" \
|
||||
.. \
|
||||
&& make VERBOSE=1
|
||||
|
||||
# Install prometheus-client-c.
|
||||
RUN LIBS_DIR=/out/$(dirname $(find /usr/ -name libc.so)) \
|
||||
&& mkdir -p $LIBS_DIR/ \
|
||||
&& cp -rf /build/prom/build/libprom.so \
|
||||
/build/promhttp/build/libpromhttp.so \
|
||||
$LIBS_DIR/ \
|
||||
&& mkdir -p /out/usr/include/ \
|
||||
&& cp -rf /build/prom/include/* \
|
||||
/build/promhttp/include/* \
|
||||
/out/usr/include/ \
|
||||
# Preserve license file.
|
||||
&& mkdir -p /out/usr/share/licenses/prometheus-client-c/ \
|
||||
|
||||
@ -465,6 +465,13 @@ cert=/etc/ssl/certs/cert.pem
|
||||
#
|
||||
pkey=/etc/ssl/private/privkey.pem
|
||||
|
||||
# Raw public keys support.
|
||||
# On/off switch for RFC-7250 aka raw public keys.
|
||||
# Keep in mind, in order for rpks to work,
|
||||
# coturn must be built against openSSL version at least 3.2.1
|
||||
#
|
||||
#raw-public-keys
|
||||
|
||||
# Private key file password, if it is in encoded format.
|
||||
# This option has no default value.
|
||||
#
|
||||
@ -594,14 +601,14 @@ syslog
|
||||
#
|
||||
#stun-only
|
||||
|
||||
# Option to hide software version. Enhance security when used in production.
|
||||
# Option to show software version - disabled by default.
|
||||
# Revealing the specific software version of the agent through the
|
||||
# SOFTWARE attribute might allow them to become more vulnerable to
|
||||
# attacks against software that is known to contain security holes.
|
||||
# Implementers SHOULD make usage of the SOFTWARE attribute a
|
||||
# configurable option (https://tools.ietf.org/html/rfc5389#section-16.1.2)
|
||||
# configurable option (https://datatracker.ietf.org/doc/html/rfc8489#section-16.1.2)
|
||||
#
|
||||
#no-software-attribute
|
||||
#software-attribute
|
||||
|
||||
# Option to suppress STUN functionality, only TURN requests will be processed.
|
||||
# Run as TURN server only, all STUN requests will be ignored.
|
||||
|
||||
@ -11,10 +11,10 @@ PREFIX/share/turnserver/schema.sql file after the turnserver installation:
|
||||
|
||||
If you would like to created a new fresh SQLite TURN database:
|
||||
|
||||
$ sqlite3 <your-db-file-name> < turndb/schema.sql
|
||||
$ `sqlite3 <your-db-file-name> < turndb/schema.sql`
|
||||
|
||||
The schema description:
|
||||
|
||||
```
|
||||
# Table for long-term credentials mechanism authorization:
|
||||
#
|
||||
CREATE TABLE turnusers_lt (
|
||||
@ -23,6 +23,7 @@ CREATE TABLE turnusers_lt (
|
||||
hmackey char(128),
|
||||
PRIMARY KEY (realm,name)
|
||||
);
|
||||
```
|
||||
|
||||
The field hmackey contains HEX string representation of the key.
|
||||
We do not store the user open passwords for long-term credentials, for
|
||||
@ -31,7 +32,7 @@ if you change the realm, you will have to update the HMAC keys of all
|
||||
users, because the realm is used for the HMAC key generation.
|
||||
|
||||
The key must be up to 32 characters (HEX representation of 16 bytes) for SHA1:
|
||||
|
||||
```
|
||||
# Table holding shared secrets for secret-based authorization
|
||||
# (REST API). Shared secret can be stored either in unsecure open
|
||||
# plain form, or in encrypted form (see turnadmin docs).
|
||||
@ -94,6 +95,7 @@ CREATE TABLE oauth_key (
|
||||
realm varchar(127) default '',
|
||||
primary key (kid)
|
||||
);
|
||||
```
|
||||
|
||||
The oauth_key table fields meanings are:
|
||||
|
||||
@ -113,7 +115,7 @@ The oauth_key table fields meanings are:
|
||||
The default value is "A256GCM";
|
||||
|
||||
realm - (optional) can be used to set the user realm (if the field is not empty).
|
||||
|
||||
```
|
||||
# Https access admin users.
|
||||
# Leave this table empty if you do not want
|
||||
# remote https access to the admin functions.
|
||||
@ -126,6 +128,7 @@ CREATE TABLE admin_user (
|
||||
password varchar(127),
|
||||
primary key (name)
|
||||
);
|
||||
```
|
||||
|
||||
You can use turnadmin program to manage the database - you can either use
|
||||
turnadmin to add/modify/delete users, or you can use turnadmin to produce
|
||||
@ -133,7 +136,7 @@ the hmac keys and modify the database with your favorite tools.
|
||||
|
||||
When starting the turnserver, the --db parameter will be, for example:
|
||||
|
||||
turnserver ... --db="/var/db/turndb"
|
||||
`turnserver ... --db="/var/db/turndb"`
|
||||
|
||||
You will have to use the program turnadmin to fill the
|
||||
database, or you can do that manually with psql.
|
||||
@ -142,14 +145,14 @@ Fill in users, for example:
|
||||
|
||||
Shared secret for the TURN REST API (realm north.gov):
|
||||
|
||||
$ bin/turnadmin -s logen -r north.gov -b "/var/db/turndb"
|
||||
$ `bin/turnadmin -s logen -r north.gov -b "/var/db/turndb"`
|
||||
|
||||
Long-term credentials mechanism:
|
||||
|
||||
$ bin/turnadmin -a -b "/var/db/turndb" -u gorst -r north.gov -p hero
|
||||
$ bin/turnadmin -a -b "/var/db/turndb" -u ninefingers -r north.gov -p youhavetoberealistic
|
||||
$ `bin/turnadmin -a -b "/var/db/turndb" -u gorst -r north.gov -p hero` \
|
||||
$ `bin/turnadmin -a -b "/var/db/turndb" -u ninefingers -r north.gov -p youhavetoberealistic`
|
||||
|
||||
Admin users:
|
||||
|
||||
$ bin/turnadmin -A -b "/var/db/turndb" -u gorst -p hero
|
||||
$ bin/turnadmin -A -b "/var/db/turndb" -u ninefingers -p youhavetoberealistic -r north.gov
|
||||
$ `bin/turnadmin -A -b "/var/db/turndb" -u gorst -p hero` \
|
||||
$ `bin/turnadmin -A -b "/var/db/turndb" -u ninefingers -p youhavetoberealistic -r north.gov`
|
||||
|
||||
@ -54,9 +54,22 @@
|
||||
#tcp-proxy-port=5555
|
||||
|
||||
# Listener IP address of relay server. Multiple listeners can be specified.
|
||||
# If no IP(s) specified in the config file or in the command line options,
|
||||
# then all IPv4 and IPv6 system IPs will be used for listening.
|
||||
# If no IP is specified in the config file or in the command line options,
|
||||
# then all IPv4 system IPs will be used for listening.
|
||||
#listening-ip=
|
||||
#
|
||||
# If you specify '::' as IP, then all IPv6 system IPs will be used for
|
||||
# listening.
|
||||
#listening-ip=::
|
||||
#
|
||||
# If you want to listen on all IPv4 as well as on all IPv6, you can do
|
||||
#listening-ip=
|
||||
#listening-ip=::
|
||||
# or
|
||||
#listening-ip=0.0.0.0
|
||||
#listening-ip=::
|
||||
#
|
||||
# to specify just some IPs you prefer:
|
||||
#listening-ip=172.17.19.101
|
||||
#listening-ip=10.207.21.238
|
||||
#listening-ip=2607:f0d0:1002:51::4
|
||||
@ -200,6 +213,16 @@
|
||||
#
|
||||
#prometheus
|
||||
|
||||
# Enable labeling prometheus traffic metrics with client usernames.
|
||||
# Labeling with client usernames is disabled by default, because this may cause memory
|
||||
# leaks when using authentication with ephemeral usernames (e.g. TURN REST API).
|
||||
#
|
||||
#prometheus-username-labels
|
||||
|
||||
# Prometheus listener port (Default: 9641).
|
||||
#
|
||||
#prometheus-port=9641
|
||||
|
||||
# TURN REST API flag.
|
||||
# (Time Limited Long Term Credential)
|
||||
# Flag that sets a special authorization option that is based upon authentication secret.
|
||||
@ -467,6 +490,13 @@
|
||||
#
|
||||
#pkey=/usr/local/etc/turn_server_pkey.pem
|
||||
|
||||
# Raw public keys support.
|
||||
# On/off switch for RFC-7250 aka raw public keys.
|
||||
# Keep in mind, in order for rpks to work,
|
||||
# coturn must be built against openSSL version at least 3.2.1
|
||||
#
|
||||
#raw-public-keys
|
||||
|
||||
# Private key file password, if it is in encoded format.
|
||||
# This option has no default value.
|
||||
#
|
||||
|
||||
@ -1,14 +1,20 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect cmake build and adjust path
|
||||
BINDIR="../bin"
|
||||
if [ ! -f $BINDIR/turnserver ]; then
|
||||
BINDIR="../build/bin"
|
||||
fi
|
||||
|
||||
echo 'Running turnserver'
|
||||
../bin/turnserver --use-auth-secret --static-auth-secret=secret --realm=north.gov --allow-loopback-peers --no-cli --cert ../examples/ca/turn_server_cert.pem --pkey ../examples/ca/turn_server_pkey.pem > /dev/null &
|
||||
$BINDIR/turnserver --use-auth-secret --static-auth-secret=secret --realm=north.gov --allow-loopback-peers --no-cli --cert ../examples/ca/turn_server_cert.pem --pkey ../examples/ca/turn_server_pkey.pem > /dev/null &
|
||||
echo 'Running peer client'
|
||||
../bin/turnutils_peer -L 127.0.0.1 -L ::1 -L 0.0.0.0 > /dev/null &
|
||||
$BINDIR/turnutils_peer -L 127.0.0.1 -L ::1 -L 0.0.0.0 > /dev/null &
|
||||
|
||||
sleep 2
|
||||
|
||||
echo 'Running turn client TCP'
|
||||
../bin/turnutils_uclient -t -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
$BINDIR/turnutils_uclient -t -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
@ -17,7 +23,7 @@ else
|
||||
fi
|
||||
|
||||
echo 'Running turn client TLS'
|
||||
../bin/turnutils_uclient -t -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
$BINDIR/turnutils_uclient -t -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
@ -26,7 +32,7 @@ else
|
||||
fi
|
||||
|
||||
echo 'Running turn client UDP'
|
||||
../bin/turnutils_uclient -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
$BINDIR/turnutils_uclient -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
@ -35,7 +41,7 @@ else
|
||||
fi
|
||||
|
||||
echo 'Running turn client DTLS'
|
||||
../bin/turnutils_uclient -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
$BINDIR/turnutils_uclient -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
|
||||
59
examples/run_tests_conf.sh
Executable file
59
examples/run_tests_conf.sh
Executable file
@ -0,0 +1,59 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Detect cmake build and adjust path
|
||||
BINDIR="../bin"
|
||||
if [ ! -f $BINDIR/turnserver ]; then
|
||||
BINDIR="../build/bin"
|
||||
fi
|
||||
|
||||
echo "Creating $BINDIR/turnserver.conf file"
|
||||
echo "use-auth-secret" > $BINDIR/turnserver.conf
|
||||
echo "static-auth-secret=secret" >> $BINDIR/turnserver.conf
|
||||
echo "realm=north.gov" >> $BINDIR/turnserver.conf
|
||||
echo "allow-loopback-peers" >> $BINDIR/turnserver.conf
|
||||
echo "no-cli" >> $BINDIR/turnserver.conf
|
||||
echo "cert=../examples/ca/turn_server_cert.pem" >> $BINDIR/turnserver.conf
|
||||
echo "pkey=../examples/ca/turn_server_pkey.pem" >> $BINDIR/turnserver.conf
|
||||
|
||||
echo 'Running turnserver'
|
||||
$BINDIR/turnserver -c $BINDIR/turnserver.conf > /dev/null &
|
||||
echo 'Running peer client'
|
||||
$BINDIR/turnutils_peer -L 127.0.0.1 -L ::1 -L 0.0.0.0 > /dev/null &
|
||||
|
||||
sleep 2
|
||||
|
||||
echo 'Running turn client TCP'
|
||||
$BINDIR/turnutils_uclient -t -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo FAIL
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo 'Running turn client TLS'
|
||||
$BINDIR/turnutils_uclient -t -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo FAIL
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo 'Running turn client UDP'
|
||||
$BINDIR/turnutils_uclient -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo FAIL
|
||||
exit $?
|
||||
fi
|
||||
|
||||
echo 'Running turn client DTLS'
|
||||
$BINDIR/turnutils_uclient -S -e 127.0.0.1 -X -g -u user -W secret 127.0.0.1 | grep "start_mclient: tot_send_bytes ~ 1000, tot_recv_bytes ~ 1000" > /dev/null
|
||||
if [ $? -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo FAIL
|
||||
exit $?
|
||||
fi
|
||||
73
examples/run_tests_prom.sh
Executable file
73
examples/run_tests_prom.sh
Executable file
@ -0,0 +1,73 @@
|
||||
#!/bin/bash
|
||||
|
||||
|
||||
# Detect cmake build and adjust path
|
||||
BINDIR="../bin"
|
||||
if [ ! -f $BINDIR/turnserver ]; then
|
||||
BINDIR="../build/bin"
|
||||
fi
|
||||
|
||||
function assert_prom_no_response() {
|
||||
wget --quiet --output-document=/dev/null --tries=1 "$1"
|
||||
status="$?"
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo FAIL
|
||||
exit 1
|
||||
else
|
||||
echo OK
|
||||
fi
|
||||
}
|
||||
|
||||
function assert_prom_response() {
|
||||
# Match something that looks like the expected body
|
||||
wget --quiet --output-document=- --tries=1 "$1" | grep 'TYPE\|HELP\|counter\|gauge' >/dev/null
|
||||
status="$?"
|
||||
if [ "$status" -eq 0 ]; then
|
||||
echo OK
|
||||
else
|
||||
echo FAIL
|
||||
exit "$status"
|
||||
fi
|
||||
}
|
||||
|
||||
echo "Running without prometheus"
|
||||
$BINDIR/turnserver /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_no_response "http://localhost:9641/metrics"
|
||||
kill "$turnserver_pid"
|
||||
|
||||
echo "Running turnserver with prometheus, using defaults"
|
||||
$BINDIR/turnserver --prometheus > /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_response "http://localhost:9641/metrics"
|
||||
kill "$turnserver_pid"
|
||||
|
||||
echo "Running turnserver with prometheus, using custom address"
|
||||
$BINDIR/turnserver --prometheus --prometheus-address="127.0.0.1" > /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_response "http://127.0.0.1:9641/metrics"
|
||||
kill "$turnserver_pid"
|
||||
|
||||
echo "Running turnserver with prometheus, using custom port"
|
||||
$BINDIR/turnserver --prometheus --prometheus-port="8080" > /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_response "http://localhost:8080/metrics"
|
||||
kill "$turnserver_pid"
|
||||
|
||||
echo "Running turnserver with prometheus, using custom address and port"
|
||||
$BINDIR/turnserver --prometheus --prometheus-address="127.0.0.1" --prometheus-port="8080" > /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_response "http://127.0.0.1:8080/metrics"
|
||||
kill "$turnserver_pid"
|
||||
|
||||
echo "Running turnserver with prometheus, using custom path"
|
||||
$BINDIR/turnserver --prometheus --prometheus-path="/coturn/metrics" > /dev/null &
|
||||
turnserver_pid="$!"
|
||||
sleep 2
|
||||
assert_prom_response "http://localhost:9641/coturn/metrics"
|
||||
kill "$turnserver_pid"
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
# Run it from the root of the coturn source tree
|
||||
|
||||
V=4.5.2
|
||||
V=4.6.3
|
||||
|
||||
PACKDIR=`pwd`/../coturn-releases/
|
||||
SRCDIR=`pwd`
|
||||
|
||||
@ -24,7 +24,6 @@ extern int LLVMFuzzerTestOneInput(const uint8_t *Data,
|
||||
uint8_t realm[33];
|
||||
uint8_t upwd[33];
|
||||
strcpy((char *)upwd, "VOkJxbRl1RmTxUk/WvJxBt");
|
||||
stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, (uint8_t *)Data,
|
||||
Size, uname, realm, upwd, shatype);
|
||||
stun_check_message_integrity_str(TURN_CREDENTIALS_SHORT_TERM, (uint8_t *)Data, Size, uname, realm, upwd, shatype);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
|
||||
# Common settings script.
|
||||
|
||||
TURNVERSION=4.5.2
|
||||
TURNVERSION=4.6.3
|
||||
BUILDDIR=~/rpmbuild
|
||||
ARCH=`uname -p`
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
Name: turnserver
|
||||
Version: 4.6.2
|
||||
Version: 4.6.3
|
||||
Release: 0%{dist}
|
||||
Summary: Coturn TURN Server
|
||||
|
||||
|
||||
175
scripts/install_coturn_on_aws_ec2.sh
Normal file
175
scripts/install_coturn_on_aws_ec2.sh
Normal file
@ -0,0 +1,175 @@
|
||||
#!/bin/bash
|
||||
#####################################################################################
|
||||
############## purpose : install coturn as a server ########
|
||||
############## verification on aws : tested & verified on aws ec2 ########
|
||||
############## platform : aws ec2 ########
|
||||
############## aws ubuntu version : ubuntu 22.04 LTS ########
|
||||
############## coturn base version : 4.6.3 ########
|
||||
############## dependent tools : installs prometheus client as well ########
|
||||
############## file permissions : chmod 777 install_coturn_on_aws_ec2.sh #####
|
||||
############## run command : ./install_coturn_on_aws_ec2.sh ########
|
||||
############## developer : hariprasad.t@samsung.com ########
|
||||
#####################################################################################
|
||||
|
||||
coturn_package="https://github.com/coturn/coturn/archive/refs/tags/4.6.3.tar.gz"
|
||||
coturn_version="4.6.3"
|
||||
|
||||
if [ "$#" -eq 0 ]
|
||||
then
|
||||
echo "coturn version is not supplied as argument, installing below version as default."
|
||||
echo "default coturn package: $coturn_package"
|
||||
else
|
||||
coturn_package="https://github.com/coturn/coturn/archive/refs/tags/$1.tar.gz"
|
||||
coturn_version="$1"
|
||||
echo "installing coturn package: $coturn_package"
|
||||
fi
|
||||
|
||||
echo "--------> this script installs coturn server version $1 on aws ec2 instance..."
|
||||
|
||||
echo "--------> create user turnserver..."
|
||||
sudo adduser --gecos "" --disabled-password turnserver
|
||||
|
||||
echo "--------> updating packages..."
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y update
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get -y upgrade
|
||||
|
||||
### install all dependent packages
|
||||
echo "--------> installing dependent packages..."
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y gcc make openssl-dev build-essential pkg-config libsystemd-dev musl-dev sqlite
|
||||
sudo DEBIAN_FRONTEND=noninteractive apt-get install -y libssl-dev libsqlite3-dev libevent-dev libpq-dev libmysqlclient-dev libhiredis-dev libmicrohttpd-dev
|
||||
|
||||
### download prometheus client libraries
|
||||
echo "--------> installing prometheus client..."
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libprom-dev-0.1.3-Linux.deb
|
||||
wget https://github.com/digitalocean/prometheus-client-c/releases/download/v0.1.3/libpromhttp-dev-0.1.3-Linux.deb
|
||||
sudo dpkg -i prometheus-client/libprom-dev-0.1.3-Linux.deb
|
||||
sudo dpkg -i prometheus-client/libpromhttp-dev-0.1.3-Linux.deb
|
||||
|
||||
### download coturn source code
|
||||
echo "--------> downloading coturn $coturn_package"
|
||||
wget "$coturn_package"
|
||||
tar -xf "$coturn_version.tar.gz"
|
||||
cd "coturn-$coturn_version"
|
||||
./configure
|
||||
|
||||
### compile & install coturn
|
||||
make
|
||||
echo "--------> installing coturn ..."
|
||||
sudo make install
|
||||
|
||||
sudo bash -c "cat > /etc/default/coturn << EOL
|
||||
TURNSERVER_ENABLED=1
|
||||
EXTRA_OPTIONS=-v
|
||||
EOL"
|
||||
|
||||
echo "--------> generating random key for realm..."
|
||||
secret_key=$(bash -c 'openssl rand -hex 32')
|
||||
|
||||
### fetch ec2 public ip and private ip using metadata token (applicable for v2 version of metadata)
|
||||
echo "--------> retrieving public & private ips of ec2 instance..."
|
||||
aws_token=$(bash -c 'curl -s -X PUT "http://instance-data/latest/api/token" -H "X-aws-ec2-metadata-token-ttl-seconds: 21600"')
|
||||
public_ip=$(bash -c 'curl -s -H "X-aws-ec2-metadata-token:'$aws_token'" -X GET "http://instance-data/latest/meta-data/public-ipv4"')
|
||||
private_ip=$(bash -c 'curl -s -H "X-aws-ec2-metadata-token:'$aws_token'" -X GET "http://instance-data/latest/meta-data/local-ipv4"')
|
||||
|
||||
echo "--------> public ip: $public_ip, private ip: $private_ip"
|
||||
|
||||
sudo bash -c "mv /etc/turnserver.conf /etc/turnserver.conf.original"
|
||||
|
||||
### create configuration file for coturn with basic expected parameters
|
||||
### change below values as per your requirement.. like ports, username, password, etc.
|
||||
echo "--------> applying new config changes..."
|
||||
sudo bash -c "cat > /etc/turnserver.conf << EOL
|
||||
listening-port=3478
|
||||
tls-listening-port=5349
|
||||
# allow only TLSv1.2+
|
||||
no-tlsv1
|
||||
no-tlsv1_1
|
||||
userdb=/usr/local/var/db/turndb
|
||||
no-cli
|
||||
min-port=45000
|
||||
max-port=65535
|
||||
log-file=/var/log/turnserver/turnserver.log
|
||||
verbose
|
||||
fingerprint
|
||||
realm=${secret_key}
|
||||
lt-cred-mech
|
||||
user=username:password
|
||||
external-ip=${public_ip}/${private_ip}
|
||||
new-log-timestamp
|
||||
new-log-timestamp-format \"%FT%T%z\"
|
||||
log-binding
|
||||
prometheus
|
||||
EOL"
|
||||
|
||||
### make coturn as auto recoverable by making it as a service
|
||||
sudo bash -c "cat > /lib/systemd/system/coturn.service << EOL
|
||||
[Unit]
|
||||
Description=coTURN STUN Server
|
||||
Documentation=man:coturn(1) man:turnadmin(1) man:turnserver(1)
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
User=turnserver
|
||||
Group=turnserver
|
||||
Type=notify
|
||||
EnvironmentFile=/etc/default/coturn
|
||||
ExecStart=/usr/local/bin/turnserver -c /etc/turnserver.conf --pidfile=
|
||||
Restart=on-failure
|
||||
InaccessibleDirectories=/home
|
||||
PrivateTmp=yes
|
||||
LimitCORE=infinity
|
||||
LimitNOFILE=1000000
|
||||
LimitNPROC=60000
|
||||
LimitRTPRIO=infinity
|
||||
LimitRTTIME=7000000
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
EOL"
|
||||
|
||||
### memory based database configurations
|
||||
sudo bash -c "sudo mkdir -p /var/lib/turn/turndb"
|
||||
sudo bash -c "sudo chown turnserver:turnserver /var/lib/turn/turndb"
|
||||
|
||||
### apply log rotation policy to avoid "disk full" issues
|
||||
echo "--------> setting log rotation policy..."
|
||||
sudo bash -c "sudo mkdir -p /var/log/turnserver"
|
||||
sudo bash -c "sudo chown turnserver:turnserver /var/log/turnserver"
|
||||
sudo bash -c "cat > /etc/logrotate.d/coturn << EOL
|
||||
/var/log/turnserver/*.log
|
||||
{
|
||||
rotate 7
|
||||
daily
|
||||
missingok
|
||||
notifempty
|
||||
compress
|
||||
postrotate
|
||||
/bin/systemctl kill -s HUP coturn.service
|
||||
endscript
|
||||
}
|
||||
EOL"
|
||||
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw allow 3478/udp
|
||||
sudo ufw allow 5349/tcp
|
||||
|
||||
#Running coTURN on privileged port 443
|
||||
sudo bash -c "setcap cap_net_bind_service=+ep /usr/local/bin/turnserver"
|
||||
|
||||
sudo bash -c "sudo chown turnserver:turnserver /etc/default/coturn"
|
||||
sudo bash -c "sudo chown turnserver:turnserver /etc/turnserver.conf"
|
||||
|
||||
echo "--------> starting coturn as a service..."
|
||||
sudo systemctl enable coturn.service
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl restart coturn.service
|
||||
echo "--------> coturn is running successfully..."
|
||||
|
||||
####
|
||||
echo "------ verification steps after installation -------"
|
||||
echo "a. check with command: ps -eaf | grep turnserver"
|
||||
echo "b. check with command: systemctl status coturn"
|
||||
echo "c. check configuration: cat /etc/turnserver.conf"
|
||||
echo "----------------------------------------------------"
|
||||
####
|
||||
@ -40,6 +40,9 @@ endif()
|
||||
find_package(Libevent CONFIG)
|
||||
if(Libevent_FOUND)
|
||||
list(APPEND COMMON_LIBS libevent::core libevent::extra libevent::openssl)
|
||||
if(NOT WIN32)
|
||||
list(APPEND COMMON_LIBS libevent::pthreads)
|
||||
endif()
|
||||
else()
|
||||
find_package(Libevent MODULE)
|
||||
if(Libevent_FOUND)
|
||||
@ -49,15 +52,6 @@ else()
|
||||
message(FATAL_ERROR "Must set Libevent")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(hiredis)
|
||||
if(hiredis_FOUND)
|
||||
list(APPEND SOURCE_FILES hiredis_libevent2.c)
|
||||
list(APPEND HEADER_FILES hiredis_libevent2.h)
|
||||
list(APPEND COMMON_LIBS hiredis::hiredis)
|
||||
else()
|
||||
list(APPEND COMMON_DEFINED TURN_NO_HIREDIS)
|
||||
endif()
|
||||
message("COMMON_LIBS:${COMMON_LIBS}")
|
||||
|
||||
add_library(${PROJECT_NAME} STATIC ${SOURCE_FILES} ${HEADER_FILES})
|
||||
|
||||
@ -38,8 +38,12 @@
|
||||
#if defined(__unix__) || defined(unix) || defined(__APPLE__)
|
||||
#include <getopt.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) || defined(unix) || defined(__APPLE__) || defined(__MINGW32__)
|
||||
#include <libgen.h>
|
||||
#endif
|
||||
|
||||
#if defined(__unix__) || defined(unix)
|
||||
#include <pthread.h>
|
||||
#include <sys/resource.h>
|
||||
@ -106,7 +110,7 @@ int set_sock_buf_size(evutil_socket_t fd, int sz0) {
|
||||
|
||||
sz = sz0;
|
||||
while (sz > 0) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *)(&sz), (socklen_t)sizeof(sz)) < 0) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (const void *)&sz, (socklen_t)sizeof(sz)) < 0) {
|
||||
sz = sz / 2;
|
||||
} else {
|
||||
break;
|
||||
@ -120,7 +124,7 @@ int set_sock_buf_size(evutil_socket_t fd, int sz0) {
|
||||
|
||||
sz = sz0;
|
||||
while (sz > 0) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *)(&sz), (socklen_t)sizeof(sz)) < 0) {
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (const void *)&sz, (socklen_t)sizeof(sz)) < 0) {
|
||||
sz = sz / 2;
|
||||
} else {
|
||||
break;
|
||||
@ -183,9 +187,9 @@ int socket_tcp_set_keepalive(evutil_socket_t fd, SOCKET_TYPE st) {
|
||||
int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) {
|
||||
UNUSED_ARG(st);
|
||||
|
||||
if (fd < 0)
|
||||
if (fd < 0) {
|
||||
return -1;
|
||||
else {
|
||||
} else {
|
||||
|
||||
#if defined(WINDOWS)
|
||||
int use_reuseaddr = IS_TURN_SERVER;
|
||||
@ -197,8 +201,9 @@ int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) {
|
||||
if (use_reuseaddr) {
|
||||
int on = flag;
|
||||
int ret = setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (const void *)&on, (socklen_t)sizeof(on));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
perror("SO_REUSEADDR");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -208,8 +213,9 @@ int socket_set_reusable(evutil_socket_t fd, int flag, SOCKET_TYPE st) {
|
||||
if (is_sctp_socket(st)) {
|
||||
int on = flag;
|
||||
int ret = setsockopt(fd, IPPROTO_SCTP, SCTP_REUSE_PORT, (const void *)&on, (socklen_t)sizeof(on));
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
perror("SCTP_REUSE_PORT");
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@ -237,11 +243,12 @@ int sock_bind_to_device(evutil_socket_t fd, const unsigned char *ifname) {
|
||||
|
||||
strncpy(ifr.ifr_name, (const char *)ifname, sizeof(ifr.ifr_name));
|
||||
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (void *)&ifr, sizeof(ifr)) < 0) {
|
||||
if (socket_eperm())
|
||||
if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, (const void *)&ifr, sizeof(ifr)) < 0) {
|
||||
if (socket_eperm()) {
|
||||
perror("You must obtain superuser privileges to bind a socket to device");
|
||||
else
|
||||
} else {
|
||||
perror("Cannot bind socket to device");
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
@ -255,9 +262,9 @@ int sock_bind_to_device(evutil_socket_t fd, const unsigned char *ifname) {
|
||||
}
|
||||
|
||||
int addr_connect(evutil_socket_t fd, const ioa_addr *addr, int *out_errno) {
|
||||
if (!addr || fd < 0)
|
||||
if (!addr || fd < 0) {
|
||||
return -1;
|
||||
else {
|
||||
} else {
|
||||
int err = 0;
|
||||
do {
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
@ -269,11 +276,13 @@ int addr_connect(evutil_socket_t fd, const ioa_addr *addr, int *out_errno) {
|
||||
}
|
||||
} while (err < 0 && socket_eintr());
|
||||
|
||||
if (out_errno)
|
||||
if (out_errno) {
|
||||
*out_errno = socket_errno();
|
||||
}
|
||||
|
||||
if (err < 0 && !socket_einprogress())
|
||||
if (err < 0 && !socket_einprogress()) {
|
||||
perror("Connect");
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
@ -296,7 +305,7 @@ int addr_bind(evutil_socket_t fd, const ioa_addr *addr, int reusable, int debug,
|
||||
} while (ret < 0 && socket_eintr());
|
||||
} else if (addr->ss.sa_family == AF_INET6) {
|
||||
const int off = 0;
|
||||
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const char *)&off, sizeof(off));
|
||||
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, (const void *)&off, sizeof(off));
|
||||
do {
|
||||
ret = bind(fd, (const struct sockaddr *)addr, sizeof(struct sockaddr_in6));
|
||||
} while (ret < 0 && socket_eintr());
|
||||
@ -318,9 +327,9 @@ int addr_bind(evutil_socket_t fd, const ioa_addr *addr, int reusable, int debug,
|
||||
|
||||
int addr_get_from_sock(evutil_socket_t fd, ioa_addr *addr) {
|
||||
|
||||
if (fd < 0 || !addr)
|
||||
if (fd < 0 || !addr) {
|
||||
return -1;
|
||||
else {
|
||||
} else {
|
||||
|
||||
ioa_addr a;
|
||||
a.ss.sa_family = AF_INET6;
|
||||
@ -350,7 +359,7 @@ int get_raw_socket_ttl(evutil_socket_t fd, int family) {
|
||||
} while (0);
|
||||
#else
|
||||
socklen_t slen = (socklen_t)sizeof(ttl);
|
||||
if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, &slen) < 0) {
|
||||
if (getsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (void *)&ttl, &slen) < 0) {
|
||||
perror("get HOPLIMIT on socket");
|
||||
return TTL_IGNORE;
|
||||
}
|
||||
@ -363,7 +372,7 @@ int get_raw_socket_ttl(evutil_socket_t fd, int family) {
|
||||
} while (0);
|
||||
#else
|
||||
socklen_t slen = (socklen_t)sizeof(ttl);
|
||||
if (getsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, &slen) < 0) {
|
||||
if (getsockopt(fd, IPPROTO_IP, IP_TTL, (void *)&ttl, &slen) < 0) {
|
||||
perror("get TTL on socket");
|
||||
return TTL_IGNORE;
|
||||
}
|
||||
@ -386,7 +395,7 @@ int get_raw_socket_tos(evutil_socket_t fd, int family) {
|
||||
} while (0);
|
||||
#else
|
||||
socklen_t slen = (socklen_t)sizeof(tos);
|
||||
if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, &slen) < 0) {
|
||||
if (getsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, (void *)&tos, &slen) < 0) {
|
||||
perror("get TCLASS on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -399,7 +408,7 @@ int get_raw_socket_tos(evutil_socket_t fd, int family) {
|
||||
} while (0);
|
||||
#else
|
||||
socklen_t slen = (socklen_t)sizeof(tos);
|
||||
if (getsockopt(fd, IPPROTO_IP, IP_TOS, &tos, &slen) < 0) {
|
||||
if (getsockopt(fd, IPPROTO_IP, IP_TOS, (void *)&tos, &slen) < 0) {
|
||||
perror("get TOS on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -419,7 +428,7 @@ int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl) {
|
||||
UNUSED_ARG(ttl);
|
||||
#else
|
||||
CORRECT_RAW_TTL(ttl);
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &ttl, sizeof(ttl)) < 0) {
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, (const void *)&ttl, sizeof(ttl)) < 0) {
|
||||
perror("set HOPLIMIT on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -430,7 +439,7 @@ int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl) {
|
||||
UNUSED_ARG(ttl);
|
||||
#else
|
||||
CORRECT_RAW_TTL(ttl);
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_TTL, &ttl, sizeof(ttl)) < 0) {
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_TTL, (const void *)&ttl, sizeof(ttl)) < 0) {
|
||||
perror("set TTL on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -448,7 +457,7 @@ int set_raw_socket_tos(evutil_socket_t fd, int family, int tos) {
|
||||
UNUSED_ARG(tos);
|
||||
#else
|
||||
CORRECT_RAW_TOS(tos);
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &tos, sizeof(tos)) < 0) {
|
||||
if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, (const void *)&tos, sizeof(tos)) < 0) {
|
||||
perror("set TCLASS on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -458,7 +467,7 @@ int set_raw_socket_tos(evutil_socket_t fd, int family, int tos) {
|
||||
UNUSED_ARG(fd);
|
||||
UNUSED_ARG(tos);
|
||||
#else
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)) < 0) {
|
||||
if (setsockopt(fd, IPPROTO_IP, IP_TOS, (const void *)&tos, sizeof(tos)) < 0) {
|
||||
perror("set TOS on socket");
|
||||
return -1;
|
||||
}
|
||||
@ -468,12 +477,6 @@ int set_raw_socket_tos(evutil_socket_t fd, int family, int tos) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Signal change to add cpu pinning
|
||||
|
||||
int set_raw_socket_incoming_cpu(evutil_socket_t fd, int cpu) {
|
||||
return setsockopt(fd, SOL_SOCKET, SO_INCOMING_CPU, &cpu, sizeof(cpu));
|
||||
}
|
||||
|
||||
int is_stream_socket(int st) {
|
||||
switch (st) {
|
||||
case TCP_SOCKET:
|
||||
@ -534,40 +537,6 @@ const char *socket_type_name(SOCKET_TYPE st) {
|
||||
return "UNKNOWN";
|
||||
}
|
||||
|
||||
const char *duration_name(unsigned long duration) {
|
||||
if (duration < 60) {
|
||||
return "1min";
|
||||
} else if (duration < 600) {
|
||||
return "10mins";
|
||||
} else if (duration < 86400) {
|
||||
return "24hrs";
|
||||
} else {
|
||||
return "days";
|
||||
}
|
||||
}
|
||||
|
||||
const char *rate_name(unsigned long rate_kbps) {
|
||||
if (rate_kbps < 1) {
|
||||
return "1kbps";
|
||||
} else if (rate_kbps < 50) {
|
||||
return "50kbps";
|
||||
} else if (rate_kbps < 2500) {
|
||||
return "2500kbps";
|
||||
} else {
|
||||
return "10000kbps";
|
||||
}
|
||||
}
|
||||
|
||||
const char *addr_family_name(int addr_family) {
|
||||
if (addr_family == AF_INET) {
|
||||
return "ipv4";
|
||||
} else if (addr_family == AF_INET6) {
|
||||
return "ipv6";
|
||||
} else {
|
||||
return "other";
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////// MTU /////////////////////////////////////////
|
||||
|
||||
int set_socket_df(evutil_socket_t fd, int family, int value) {
|
||||
@ -579,10 +548,10 @@ int set_socket_df(evutil_socket_t fd, int family, int value) {
|
||||
const int val = value;
|
||||
/* kernel sets DF bit on outgoing IP packets */
|
||||
if (family == AF_INET) {
|
||||
ret = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_IP, IP_DONTFRAG, (const void *)&val, sizeof(val));
|
||||
} else {
|
||||
#if defined(IPV6_DONTFRAG) && defined(IPPROTO_IPV6)
|
||||
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, &val, sizeof(val));
|
||||
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_DONTFRAG, (const void *)&val, sizeof(val));
|
||||
#else
|
||||
#error CANNOT SET IPV6 SOCKET DF FLAG (1)
|
||||
#endif
|
||||
@ -599,15 +568,17 @@ int set_socket_df(evutil_socket_t fd, int family, int value) {
|
||||
/* kernel sets DF bit on outgoing IP packets */
|
||||
if (family == AF_INET) {
|
||||
int val = IP_PMTUDISC_DO;
|
||||
if (!value)
|
||||
if (!value) {
|
||||
val = IP_PMTUDISC_DONT;
|
||||
ret = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, &val, sizeof(val));
|
||||
}
|
||||
ret = setsockopt(fd, IPPROTO_IP, IP_MTU_DISCOVER, (const void *)&val, sizeof(val));
|
||||
} else {
|
||||
#if defined(IPPROTO_IPV6) && defined(IPV6_MTU_DISCOVER) && defined(IPV6_PMTUDISC_DO) && defined(IPV6_PMTUDISC_DONT)
|
||||
int val = IPV6_PMTUDISC_DO;
|
||||
if (!value)
|
||||
if (!value) {
|
||||
val = IPV6_PMTUDISC_DONT;
|
||||
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, &val, sizeof(val));
|
||||
}
|
||||
ret = setsockopt(fd, IPPROTO_IPV6, IPV6_MTU_DISCOVER, (const void *)&val, sizeof(val));
|
||||
#else
|
||||
#error CANNOT SET IPV6 SOCKET DF FLAG (2)
|
||||
#endif
|
||||
@ -630,8 +601,9 @@ int set_socket_df(evutil_socket_t fd, int family, int value) {
|
||||
static int get_mtu_from_ssl(SSL *ssl) {
|
||||
int ret = SOSO_MTU;
|
||||
#if DTLS_SUPPORTED
|
||||
if (ssl)
|
||||
if (ssl) {
|
||||
ret = BIO_ctrl(SSL_get_wbio(ssl), BIO_CTRL_DGRAM_QUERY_MTU, 0, NULL);
|
||||
}
|
||||
#else
|
||||
UNUSED_ARG(ssl);
|
||||
#endif
|
||||
@ -650,29 +622,35 @@ static void set_query_mtu(SSL *ssl) {
|
||||
|
||||
int decrease_mtu(SSL *ssl, int mtu, int verbose) {
|
||||
|
||||
if (!ssl)
|
||||
if (!ssl) {
|
||||
return mtu;
|
||||
}
|
||||
|
||||
int new_mtu = get_mtu_from_ssl(ssl);
|
||||
|
||||
if (new_mtu < 1)
|
||||
if (new_mtu < 1) {
|
||||
new_mtu = mtu;
|
||||
}
|
||||
|
||||
if (new_mtu > MAX_MTU)
|
||||
if (new_mtu > MAX_MTU) {
|
||||
mtu = MAX_MTU;
|
||||
if (new_mtu > 0 && new_mtu < MIN_MTU)
|
||||
}
|
||||
if (new_mtu > 0 && new_mtu < MIN_MTU) {
|
||||
mtu = MIN_MTU;
|
||||
else if (new_mtu < mtu)
|
||||
} else if (new_mtu < mtu) {
|
||||
mtu = new_mtu;
|
||||
else
|
||||
} else {
|
||||
mtu -= MTU_STEP;
|
||||
}
|
||||
|
||||
if (mtu < MIN_MTU)
|
||||
if (mtu < MIN_MTU) {
|
||||
mtu = MIN_MTU;
|
||||
}
|
||||
|
||||
set_query_mtu(ssl);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "1. mtu to use: %d\n", mtu);
|
||||
}
|
||||
|
||||
#if DTLS_SUPPORTED
|
||||
SSL_set_mtu(ssl, mtu);
|
||||
@ -684,21 +662,24 @@ int decrease_mtu(SSL *ssl, int mtu, int verbose) {
|
||||
|
||||
int set_mtu_df(SSL *ssl, evutil_socket_t fd, int family, int mtu, int df_value, int verbose) {
|
||||
|
||||
if (!ssl || fd < 0)
|
||||
if (!ssl || fd < 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ret = set_socket_df(fd, family, df_value);
|
||||
|
||||
if (!mtu)
|
||||
if (!mtu) {
|
||||
mtu = SOSO_MTU;
|
||||
else if (mtu < MIN_MTU)
|
||||
} else if (mtu < MIN_MTU) {
|
||||
mtu = MIN_MTU;
|
||||
else if (mtu > MAX_MTU)
|
||||
} else if (mtu > MAX_MTU) {
|
||||
mtu = MAX_MTU;
|
||||
}
|
||||
|
||||
set_query_mtu(ssl);
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "3. mtu to use: %d\n", mtu);
|
||||
}
|
||||
|
||||
#if DTLS_SUPPORTED
|
||||
|
||||
@ -708,8 +689,9 @@ int set_mtu_df(SSL *ssl, evutil_socket_t fd, int family, int mtu, int df_value,
|
||||
|
||||
#endif
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "4. new mtu: %d\n", get_mtu_from_ssl(ssl));
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -726,10 +708,10 @@ int get_socket_mtu(evutil_socket_t fd, int family, int verbose) {
|
||||
int val = 0;
|
||||
socklen_t slen = sizeof(val);
|
||||
if (family == AF_INET) {
|
||||
ret = getsockopt(fd, IPPROTO_IP, IP_MTU, &val, &slen);
|
||||
ret = getsockopt(fd, IPPROTO_IP, IP_MTU, (void *)&val, &slen);
|
||||
} else {
|
||||
#if defined(IPPROTO_IPV6) && defined(IPV6_MTU)
|
||||
ret = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU, &val, &slen);
|
||||
ret = getsockopt(fd, IPPROTO_IPV6, IPV6_MTU, (void *)&val, &slen);
|
||||
#endif
|
||||
;
|
||||
}
|
||||
@ -737,8 +719,9 @@ int get_socket_mtu(evutil_socket_t fd, int family, int verbose) {
|
||||
ret = val;
|
||||
#endif
|
||||
|
||||
if (verbose)
|
||||
if (verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: final=%d\n", __FUNCTION__, ret);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
@ -802,8 +785,9 @@ int handle_socket_error(void) {
|
||||
//////////////////// Misc utils //////////////////////////////
|
||||
|
||||
char *skip_blanks(char *s) {
|
||||
while (*s == ' ' || *s == '\t' || *s == '\n')
|
||||
while (*s == ' ' || *s == '\t' || *s == '\n') {
|
||||
++s;
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
@ -850,9 +834,9 @@ int clock_gettime(int X, struct timeval *tv) {
|
||||
frequencyToMicroseconds = 10.;
|
||||
}
|
||||
}
|
||||
if (usePerformanceCounter)
|
||||
if (usePerformanceCounter) {
|
||||
QueryPerformanceCounter(&t);
|
||||
else {
|
||||
} else {
|
||||
GetSystemTimeAsFileTime(&f);
|
||||
t.QuadPart = f.dwHighDateTime;
|
||||
t.QuadPart <<= 32;
|
||||
@ -898,15 +882,48 @@ char *dirname(char *path) {
|
||||
}
|
||||
|
||||
int n = strlen(drive) + strlen(dir);
|
||||
if (n > 0)
|
||||
if (n > 0) {
|
||||
path[n] = 0;
|
||||
else
|
||||
} else {
|
||||
return NULL;
|
||||
}
|
||||
return path;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WINDOWS)
|
||||
|
||||
/*!
|
||||
* \brief convert wchar to char
|
||||
*
|
||||
* \param pszInBuf: input buffer of wchar_t
|
||||
* \param nInSize: size of input wchar_t buffer
|
||||
* \param pszOutBuf: output buffer of char
|
||||
* \param pnOutSize: size of output char buffer
|
||||
* \return
|
||||
*/
|
||||
static char *_WTA(__in wchar_t *pszInBuf, __in int nInSize, __out char **pszOutBuf, __out int *pnOutSize) {
|
||||
if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
*pnOutSize = WideCharToMultiByte((UINT)0, (DWORD)0, pszInBuf, nInSize, NULL, 0, NULL, NULL);
|
||||
if (*pnOutSize == 0) {
|
||||
return NULL;
|
||||
}
|
||||
// add 1 for explicit nul-terminator at end.
|
||||
// if MultiByteToWideChar is provided a length for the input, it does not add space for a nul-terminator
|
||||
// and we have to add space to the allocation ourselves.
|
||||
(*pnOutSize)++;
|
||||
*pszOutBuf = malloc(*pnOutSize * sizeof(char));
|
||||
if (WideCharToMultiByte((UINT)0, (DWORD)0, pszInBuf, nInSize, *pszOutBuf, *pnOutSize, NULL, NULL) == 0) {
|
||||
free(*pszOutBuf);
|
||||
return NULL;
|
||||
} else {
|
||||
(*pszOutBuf)[*pnOutSize - 1] = '\0';
|
||||
return *pszOutBuf;
|
||||
}
|
||||
}
|
||||
|
||||
int getdomainname(char *name, size_t len) {
|
||||
DSROLE_PRIMARY_DOMAIN_INFO_BASIC *info;
|
||||
DWORD dw;
|
||||
@ -929,8 +946,9 @@ int getdomainname(char *name, size_t len) {
|
||||
strncpy(name, pszOut, n);
|
||||
name[n] = 0;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainForestName: %s\n", pszOut);
|
||||
} else
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail");
|
||||
}
|
||||
|
||||
free(pszOut);
|
||||
break;
|
||||
@ -949,8 +967,9 @@ int getdomainname(char *name, size_t len) {
|
||||
strncpy(name, pszOut, n);
|
||||
name[n] = 0;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameDns: %s\n", pszOut);
|
||||
} else
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail");
|
||||
}
|
||||
|
||||
free(pszOut);
|
||||
break;
|
||||
@ -969,8 +988,9 @@ int getdomainname(char *name, size_t len) {
|
||||
strncpy(name, pszOut, n);
|
||||
name[n] = 0;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "DomainNameFlat: %s\n", pszOut);
|
||||
} else
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "wchar convert to char fail");
|
||||
}
|
||||
|
||||
free(pszOut);
|
||||
} else {
|
||||
@ -983,57 +1003,6 @@ int getdomainname(char *name, size_t len) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief convert char to wchar
|
||||
*
|
||||
* \param pszInBuf: input buffer of wchar string
|
||||
* \param nInSize: size of wchar string
|
||||
* \param pszOutBuf: output buffer of char string
|
||||
* \param pnOutSize: size of char string
|
||||
* \return
|
||||
*/
|
||||
wchar_t *_ATW(__in char *pszInBuf, __in int nInSize, __out wchar_t **pszOutBuf, __out int *pnOutSize) {
|
||||
if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0)
|
||||
return NULL;
|
||||
// Get buffer size
|
||||
*pnOutSize = MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0);
|
||||
if (*pnOutSize == 0)
|
||||
return NULL;
|
||||
(*pnOutSize)++;
|
||||
*pszOutBuf = malloc((*pnOutSize) * sizeof(wchar_t));
|
||||
memset((void *)*pszOutBuf, 0, sizeof(wchar_t) * (*pnOutSize));
|
||||
if (MultiByteToWideChar(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize) == 0) {
|
||||
free(*pszOutBuf);
|
||||
return NULL;
|
||||
} else
|
||||
return *pszOutBuf;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief convert wchar to char
|
||||
*
|
||||
* \param pszInBuf: input buffer of char string
|
||||
* \param nInSize: size of char string
|
||||
* \param pszOutBuf: output buffer of wchar string
|
||||
* \param pnOutSize: size of wchar string
|
||||
* \return
|
||||
*/
|
||||
char *_WTA(__in wchar_t *pszInBuf, __in int nInSize, __out char **pszOutBuf, __out int *pnOutSize) {
|
||||
if (!pszInBuf || !pszOutBuf || !pnOutSize || nInSize <= 0)
|
||||
return NULL;
|
||||
*pnOutSize = WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, 0, NULL, NULL);
|
||||
if (*pnOutSize == 0)
|
||||
return NULL;
|
||||
(*pnOutSize)++;
|
||||
*pszOutBuf = malloc(*pnOutSize * sizeof(char));
|
||||
memset((void *)*pszOutBuf, 0, sizeof(char) * (*pnOutSize));
|
||||
if (WideCharToMultiByte(NULL, NULL, pszInBuf, nInSize, *pszOutBuf, *pnOutSize, NULL, NULL) == 0) {
|
||||
free(*pszOutBuf);
|
||||
return NULL;
|
||||
} else
|
||||
return *pszOutBuf;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
//////////////////// Config file search //////////////////////
|
||||
@ -1087,14 +1056,17 @@ void set_execdir(void) {
|
||||
if (_var && *_var) {
|
||||
_var = strdup(_var);
|
||||
char *edir = _var;
|
||||
if (edir[0] != '.')
|
||||
if (edir[0] != '.') {
|
||||
edir = strstr(edir, "/");
|
||||
if (edir && *edir)
|
||||
}
|
||||
if (edir && *edir) {
|
||||
edir = dirname(edir);
|
||||
else
|
||||
} else {
|
||||
edir = dirname(_var);
|
||||
if (c_execdir)
|
||||
}
|
||||
if (c_execdir) {
|
||||
free(c_execdir);
|
||||
}
|
||||
c_execdir = strdup(edir);
|
||||
free(_var);
|
||||
}
|
||||
@ -1105,16 +1077,19 @@ void print_abs_file_name(const char *msg1, const char *msg2, const char *fn) {
|
||||
absfn[0] = 0;
|
||||
|
||||
if (fn) {
|
||||
while (fn[0] && fn[0] == ' ')
|
||||
while (fn[0] && fn[0] == ' ') {
|
||||
++fn;
|
||||
}
|
||||
if (fn[0]) {
|
||||
if (fn[0] == '/') {
|
||||
STRCPY(absfn, fn);
|
||||
} else {
|
||||
if (fn[0] == '.' && fn[1] && fn[1] == '/')
|
||||
if (fn[0] == '.' && fn[1] && fn[1] == '/') {
|
||||
fn += 2;
|
||||
if (!getcwd(absfn, sizeof(absfn) - 1))
|
||||
}
|
||||
if (!getcwd(absfn, sizeof(absfn) - 1)) {
|
||||
absfn[0] = 0;
|
||||
}
|
||||
size_t blen = strlen(absfn);
|
||||
if (blen < sizeof(absfn) - 1) {
|
||||
strncpy(absfn + blen, "/", sizeof(absfn) - blen);
|
||||
@ -1131,7 +1106,7 @@ void print_abs_file_name(const char *msg1, const char *msg2, const char *fn) {
|
||||
}
|
||||
}
|
||||
|
||||
char *find_config_file(const char *config_file, int print_file_name) {
|
||||
char *find_config_file(const char *config_file) {
|
||||
char *full_path_to_config_file = NULL;
|
||||
|
||||
if (config_file && config_file[0]) {
|
||||
@ -1163,7 +1138,7 @@ char *find_config_file(const char *config_file, int print_file_name) {
|
||||
size_t celen = strlen(c_execdir);
|
||||
fnsz = sizeof(char) * (dirlen + cflen + celen + 10);
|
||||
fn = (char *)malloc(fnsz + 1);
|
||||
strncpy(fn, c_execdir, celen);
|
||||
strncpy(fn, c_execdir, fnsz);
|
||||
size_t fnlen = strlen(fn);
|
||||
if (fnlen < fnsz) {
|
||||
strncpy(fn + fnlen, "/", fnsz - fnlen);
|
||||
@ -1193,7 +1168,7 @@ char *find_config_file(const char *config_file, int print_file_name) {
|
||||
|
||||
if (!full_path_to_config_file) {
|
||||
if (strstr(config_file, "etc/") == config_file) {
|
||||
return find_config_file(config_file + 4, print_file_name);
|
||||
return find_config_file(config_file + 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1314,23 +1289,23 @@ unsigned long get_system_active_number_of_cpus(void) {
|
||||
|
||||
////////////////////// Base 64 ////////////////////////////
|
||||
|
||||
static char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
static char *decoding_table = NULL;
|
||||
static size_t mod_table[] = {0, 2, 1};
|
||||
static const size_t mod_table[] = {0, 2, 1};
|
||||
static const char encoding_table[] = {'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P',
|
||||
'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f',
|
||||
'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v',
|
||||
'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
|
||||
static const char *decoding_table = NULL;
|
||||
|
||||
char *base64_encode(const unsigned char *data, size_t input_length, size_t *output_length) {
|
||||
|
||||
*output_length = 4 * ((input_length + 2) / 3);
|
||||
|
||||
char *encoded_data = (char *)malloc(*output_length + 1);
|
||||
if (encoded_data == NULL)
|
||||
if (encoded_data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
size_t i, j;
|
||||
for (i = 0, j = 0; i < input_length;) {
|
||||
for (size_t i = 0, j = 0; i < input_length;) {
|
||||
|
||||
uint32_t octet_a = i < input_length ? data[i++] : 0;
|
||||
uint32_t octet_b = i < input_length ? data[i++] : 0;
|
||||
@ -1344,8 +1319,9 @@ char *base64_encode(const unsigned char *data, size_t input_length, size_t *outp
|
||||
encoded_data[j++] = encoding_table[(triple >> 0 * 6) & 0x3F];
|
||||
}
|
||||
|
||||
for (i = 0; i < mod_table[input_length % 3]; i++)
|
||||
for (size_t i = 0; i < mod_table[input_length % 3]; i++) {
|
||||
encoded_data[*output_length - 1 - i] = '=';
|
||||
}
|
||||
|
||||
encoded_data[*output_length] = 0;
|
||||
|
||||
@ -1354,31 +1330,36 @@ char *base64_encode(const unsigned char *data, size_t input_length, size_t *outp
|
||||
|
||||
void build_base64_decoding_table(void) {
|
||||
|
||||
decoding_table = (char *)malloc(256);
|
||||
memset(decoding_table, 0, 256);
|
||||
char *table = (char *)calloc(256, sizeof(char));
|
||||
|
||||
int i;
|
||||
for (i = 0; i < 64; i++)
|
||||
decoding_table[(unsigned char)encoding_table[i]] = (char)i;
|
||||
for (size_t i = 0; i < 64; i++) {
|
||||
table[(unsigned char)encoding_table[i]] = i;
|
||||
}
|
||||
decoding_table = table;
|
||||
}
|
||||
|
||||
unsigned char *base64_decode(const char *data, size_t input_length, size_t *output_length) {
|
||||
|
||||
if (decoding_table == NULL)
|
||||
if (decoding_table == NULL) {
|
||||
build_base64_decoding_table();
|
||||
}
|
||||
|
||||
if (input_length % 4 != 0)
|
||||
if (input_length % 4 != 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*output_length = input_length / 4 * 3;
|
||||
if (data[input_length - 1] == '=')
|
||||
if (data[input_length - 1] == '=') {
|
||||
(*output_length)--;
|
||||
if (data[input_length - 2] == '=')
|
||||
}
|
||||
if (data[input_length - 2] == '=') {
|
||||
(*output_length)--;
|
||||
}
|
||||
|
||||
unsigned char *decoded_data = (unsigned char *)malloc(*output_length);
|
||||
if (decoded_data == NULL)
|
||||
if (decoded_data == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int i;
|
||||
size_t j;
|
||||
@ -1391,12 +1372,15 @@ unsigned char *base64_decode(const char *data, size_t input_length, size_t *outp
|
||||
|
||||
uint32_t triple = (sextet_a << 3 * 6) + (sextet_b << 2 * 6) + (sextet_c << 1 * 6) + (sextet_d << 0 * 6);
|
||||
|
||||
if (j < *output_length)
|
||||
if (j < *output_length) {
|
||||
decoded_data[j++] = (triple >> 2 * 8) & 0xFF;
|
||||
if (j < *output_length)
|
||||
}
|
||||
if (j < *output_length) {
|
||||
decoded_data[j++] = (triple >> 1 * 8) & 0xFF;
|
||||
if (j < *output_length)
|
||||
}
|
||||
if (j < *output_length) {
|
||||
decoded_data[j++] = (triple >> 0 * 8) & 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
return decoded_data;
|
||||
|
||||
@ -31,10 +31,11 @@
|
||||
#ifndef __APP_LIB__
|
||||
#define __APP_LIB__
|
||||
|
||||
#include <event2/event.h>
|
||||
#include <event2/util.h> // for evutil_socket_t
|
||||
|
||||
#include "ns_turn_openssl.h"
|
||||
|
||||
#include "ns_turn_defs.h"
|
||||
#include "ns_turn_ioaddr.h"
|
||||
#include "ns_turn_ioalib.h"
|
||||
#include "ns_turn_msg_defs.h"
|
||||
@ -54,85 +55,35 @@ extern "C" {
|
||||
|
||||
extern int IS_TURN_SERVER;
|
||||
|
||||
/* ALPN */
|
||||
|
||||
#define OPENSSL_FIRST_ALPN_VERSION (0x10002003L)
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
|
||||
#define ALPN_SUPPORTED 1
|
||||
#else
|
||||
#define ALPN_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
/* TLS */
|
||||
|
||||
#if defined(TURN_NO_TLS)
|
||||
|
||||
#define TLS_SUPPORTED 0
|
||||
#define TLSv1_1_SUPPORTED 0
|
||||
#define TLSv1_2_SUPPORTED 0
|
||||
|
||||
#else
|
||||
|
||||
#define TLS_SUPPORTED 1
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_1)
|
||||
#define TLSv1_1_SUPPORTED 1
|
||||
#else
|
||||
#define TLSv1_1_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_2)
|
||||
#define TLSv1_2_SUPPORTED 1
|
||||
#else
|
||||
#define TLSv1_2_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#if defined(SSL_OP_NO_TLSv1_3)
|
||||
#define TLSv1_3_SUPPORTED 1
|
||||
#else
|
||||
#define TLSv1_3_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if defined(TURN_NO_DTLS) || (!defined(DTLS_CTRL_LISTEN) && (OPENSSL_VERSION_NUMBER < 0x10100000L))
|
||||
|
||||
#if defined(TURN_NO_DTLS)
|
||||
#define DTLS_SUPPORTED 0
|
||||
#define DTLSv1_2_SUPPORTED 0
|
||||
|
||||
#else
|
||||
|
||||
#define DTLS_SUPPORTED 1
|
||||
|
||||
#if defined(SSL_OP_NO_DTLSv1_2)
|
||||
#define DTLSv1_2_SUPPORTED 1
|
||||
#else
|
||||
#define DTLSv1_2_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= OPENSSL_FIRST_ALPN_VERSION
|
||||
#define SSL_SESSION_ECDH_AUTO_SUPPORTED 1
|
||||
#else
|
||||
#define SSL_SESSION_ECDH_AUTO_SUPPORTED 0
|
||||
#endif
|
||||
|
||||
/////////// SSL //////////////////////////
|
||||
|
||||
// clang-format off
|
||||
enum _TURN_TLS_TYPE {
|
||||
TURN_TLS_NO = 0,
|
||||
TURN_TLS_SSL23,
|
||||
TURN_TLS_v1_0,
|
||||
#if TLSv1_1_SUPPORTED
|
||||
TURN_TLS_v1_1,
|
||||
#if TLSv1_2_SUPPORTED
|
||||
TURN_TLS_v1_2,
|
||||
#endif
|
||||
#endif
|
||||
TURN_TLS_v1_3,
|
||||
TURN_TLS_TOTAL
|
||||
};
|
||||
// clang-format on
|
||||
|
||||
typedef enum _TURN_TLS_TYPE TURN_TLS_TYPE;
|
||||
|
||||
@ -205,8 +156,6 @@ int handle_socket_error(void);
|
||||
|
||||
int set_raw_socket_tos(evutil_socket_t fd, int family, int tos);
|
||||
int set_raw_socket_ttl(evutil_socket_t fd, int family, int ttl);
|
||||
// Signal change to add cpu pinning
|
||||
int set_raw_socket_incoming_cpu(evutil_socket_t fd, int cpu);
|
||||
int get_raw_socket_tos(evutil_socket_t fd, int family);
|
||||
int get_raw_socket_ttl(evutil_socket_t fd, int family);
|
||||
|
||||
@ -244,15 +193,11 @@ char *dirname(char *path);
|
||||
|
||||
#if defined(WINDOWS)
|
||||
int getdomainname(char *name, size_t len);
|
||||
// wchar convert to char
|
||||
char *_WTA(__in wchar_t *pszInBufBuf, __in int nInSize, __out char **pszOutBuf, __out int *pnOutSize);
|
||||
// char convert to wchar
|
||||
wchar_t *_ATW(__in char *pszInBuf, __in int nInSize, __out wchar_t **pszOutBuf, __out int *pnOutSize);
|
||||
#endif
|
||||
|
||||
////////////////// File search ////////////////////////
|
||||
|
||||
char *find_config_file(const char *config_file, int print_file_name);
|
||||
char *find_config_file(const char *config_file);
|
||||
void set_execdir(void);
|
||||
void print_abs_file_name(const char *msg1, const char *msg2, const char *fn);
|
||||
|
||||
|
||||
@ -31,15 +31,17 @@
|
||||
#ifndef __NST_OPENSSL_LIB__
|
||||
#define __NST_OPENSSL_LIB__
|
||||
|
||||
#include <openssl/bio.h>
|
||||
#include <openssl/bn.h>
|
||||
#include <openssl/crypto.h>
|
||||
#include <openssl/dh.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/hmac.h>
|
||||
#include <openssl/md5.h>
|
||||
#include <openssl/opensslv.h>
|
||||
#include <openssl/rand.h>
|
||||
#include <openssl/ssl.h>
|
||||
#include <openssl/bio.h> // IWYU pragma: export
|
||||
#include <openssl/bn.h> // IWYU pragma: export
|
||||
#include <openssl/crypto.h> // IWYU pragma: export
|
||||
#include <openssl/dh.h> // IWYU pragma: export
|
||||
#include <openssl/err.h> // IWYU pragma: export
|
||||
#include <openssl/evp.h> // IWYU pragma: export
|
||||
#include <openssl/hmac.h> // IWYU pragma: export
|
||||
#include <openssl/md5.h> // IWYU pragma: export
|
||||
#include <openssl/opensslv.h> // IWYU pragma: export
|
||||
#include <openssl/rand.h> // IWYU pragma: export
|
||||
#include <openssl/sha.h> // IWYU pragma: export
|
||||
#include <openssl/ssl.h> // IWYU pragma: export
|
||||
|
||||
#endif //__NST_OPENSSL_LIB__
|
||||
|
||||
@ -51,12 +51,14 @@
|
||||
|
||||
#if !defined(WINDOWS) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(__CYGWIN64__)
|
||||
#include <sys/syscall.h>
|
||||
#include <unistd.h>
|
||||
#ifdef SYS_gettid
|
||||
#define gettid() ((pid_t)syscall(SYS_gettid))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <ctype.h> // for tolower
|
||||
#include <string.h> // for memcmp, strstr, strcmp, strdup, strlen
|
||||
|
||||
////////// LOG TIME OPTIMIZATION ///////////
|
||||
|
||||
static volatile int _log_file_line_set = 0;
|
||||
@ -66,11 +68,13 @@ volatile int _log_time_value_set = 0;
|
||||
volatile turn_time_t _log_time_value = 0;
|
||||
|
||||
static inline turn_time_t log_time(void) {
|
||||
if (!log_start_time)
|
||||
if (!log_start_time) {
|
||||
log_start_time = turn_time();
|
||||
}
|
||||
|
||||
if (_log_time_value_set)
|
||||
if (_log_time_value_set) {
|
||||
return (_log_time_value - log_start_time);
|
||||
}
|
||||
|
||||
return (turn_time() - log_start_time);
|
||||
}
|
||||
@ -110,7 +114,7 @@ int turn_mutex_unlock(const turn_mutex *mutex) {
|
||||
int turn_mutex_init(turn_mutex *mutex) {
|
||||
if (mutex) {
|
||||
mutex->data = MAGIC_CODE;
|
||||
mutex->mutex = malloc(sizeof(pthread_mutex_t));
|
||||
mutex->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
pthread_mutex_init((pthread_mutex_t *)mutex->mutex, NULL);
|
||||
return 0;
|
||||
} else {
|
||||
@ -128,8 +132,8 @@ int turn_mutex_init_recursive(turn_mutex *mutex) {
|
||||
if (pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE) < 0) {
|
||||
perror("Cannot set type on mutex attr");
|
||||
} else {
|
||||
mutex->mutex = malloc(sizeof(pthread_mutex_t));
|
||||
mutex->data = MAGIC_CODE;
|
||||
mutex->mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t));
|
||||
if ((ret = pthread_mutex_init((pthread_mutex_t *)mutex->mutex, &attr)) < 0) {
|
||||
perror("Cannot init mutex");
|
||||
mutex->data = 0;
|
||||
@ -175,8 +179,9 @@ static int syslog_facility = 0;
|
||||
static int str_to_syslog_facility(char *s) {
|
||||
int i;
|
||||
for (i = 0; str_fac[i]; i++) {
|
||||
if (!strcasecmp(s, str_fac[i]))
|
||||
if (!strcasecmp(s, str_fac[i])) {
|
||||
return int_fac[i];
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
@ -218,8 +223,9 @@ void addr_debug_print(int verbose, const ioa_addr *addr, const char *s) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: EMPTY\n", s);
|
||||
} else {
|
||||
char addrbuf[INET6_ADDRSTRLEN];
|
||||
if (!s)
|
||||
if (!s) {
|
||||
s = "";
|
||||
}
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "IPv4. %s: %s:%d\n", s,
|
||||
inet_ntop(AF_INET, &addr->s4.sin_addr, addrbuf, INET6_ADDRSTRLEN), nswap16(addr->s4.sin_port));
|
||||
@ -287,8 +293,9 @@ void set_log_file_line(int set) { _log_file_line_set = set; }
|
||||
void reset_rtpprintf(void) {
|
||||
log_lock();
|
||||
if (_rtpfile) {
|
||||
if (_rtpfile != stdout)
|
||||
if (_rtpfile != stdout) {
|
||||
fclose(_rtpfile);
|
||||
}
|
||||
_rtpfile = NULL;
|
||||
}
|
||||
log_unlock();
|
||||
@ -323,9 +330,9 @@ static void set_log_file_name_func(char *base, char *f, size_t fsz) {
|
||||
len = (int)strlen(base1);
|
||||
|
||||
while (len >= 0) {
|
||||
if (base1[len] == '/')
|
||||
if (base1[len] == '/') {
|
||||
break;
|
||||
else if (base1[len] == '.') {
|
||||
} else if (base1[len] == '.') {
|
||||
free(tail);
|
||||
tail = strdup(base1 + len);
|
||||
base1[len] = 0;
|
||||
@ -382,8 +389,9 @@ static void set_rtpfile(void) {
|
||||
} else {
|
||||
set_log_file_name(log_fn_base, log_fn);
|
||||
_rtpfile = fopen(log_fn, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", log_fn);
|
||||
}
|
||||
}
|
||||
if (!_rtpfile) {
|
||||
fprintf(stderr, "ERROR: Cannot open log file for writing: %s\n", log_fn);
|
||||
@ -399,49 +407,54 @@ static void set_rtpfile(void) {
|
||||
char logtail[FILE_STR_LEN];
|
||||
char logf[FILE_STR_LEN];
|
||||
|
||||
if (simple_log)
|
||||
if (simple_log) {
|
||||
snprintf(logtail, FILE_STR_LEN, "turn.log");
|
||||
else
|
||||
} else {
|
||||
snprintf(logtail, FILE_STR_LEN, "turn_%d_", (int)getpid());
|
||||
}
|
||||
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/log/turnserver/%s", logtail) < 0)
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/log/turnserver/%s", logtail) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n");
|
||||
}
|
||||
|
||||
set_log_file_name(logbase, logf);
|
||||
|
||||
_rtpfile = fopen(logf, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
|
||||
else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/log/%s", logtail) < 0)
|
||||
} else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/log/%s", logtail) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n");
|
||||
}
|
||||
|
||||
set_log_file_name(logbase, logf);
|
||||
_rtpfile = fopen(logf, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
|
||||
else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/tmp/%s", logtail) < 0)
|
||||
} else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/var/tmp/%s", logtail) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n");
|
||||
}
|
||||
|
||||
set_log_file_name(logbase, logf);
|
||||
_rtpfile = fopen(logf, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
|
||||
else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/tmp/%s", logtail) < 0)
|
||||
} else {
|
||||
if (snprintf(logbase, FILE_STR_LEN, "/tmp/%s", logtail) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "String truncation occured.\n");
|
||||
}
|
||||
set_log_file_name(logbase, logf);
|
||||
_rtpfile = fopen(logf, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
|
||||
else {
|
||||
} else {
|
||||
snprintf(logbase, FILE_STR_LEN, "%s", logtail);
|
||||
set_log_file_name(logbase, logf);
|
||||
_rtpfile = fopen(logf, "a");
|
||||
if (_rtpfile)
|
||||
if (_rtpfile) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "log file opened: %s\n", logf);
|
||||
else {
|
||||
} else {
|
||||
_rtpfile = stdout;
|
||||
return;
|
||||
}
|
||||
@ -463,8 +476,9 @@ void set_simple_log(int val) { simple_log = val; }
|
||||
#define QUOTE(x) Q(x)
|
||||
|
||||
void rollover_logfile(void) {
|
||||
if (to_syslog || !(log_fn[0]))
|
||||
if (to_syslog || !(log_fn[0])) {
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
FILE *f = fopen(log_fn, "r");
|
||||
@ -478,8 +492,9 @@ void rollover_logfile(void) {
|
||||
}
|
||||
}
|
||||
|
||||
if (simple_log)
|
||||
if (simple_log) {
|
||||
return;
|
||||
}
|
||||
|
||||
log_lock();
|
||||
if (_rtpfile && log_fn[0] && (_rtpfile != stdout)) {
|
||||
@ -547,8 +562,9 @@ void turn_log_func_default(char *file, int line, TURN_LOG_LEVEL level, const cha
|
||||
so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "(%lu): ", (unsigned long)gettid());
|
||||
#endif
|
||||
|
||||
if (_log_file_line_set)
|
||||
if (_log_file_line_set) {
|
||||
so_far += snprintf(s + so_far, MAX_RTPPRINTF_BUFFER_SIZE - (so_far + 1), "%s(%d):", file, line);
|
||||
}
|
||||
|
||||
switch (level) {
|
||||
case TURN_LOG_LEVEL_DEBUG:
|
||||
@ -572,8 +588,9 @@ void turn_log_func_default(char *file, int line, TURN_LOG_LEVEL level, const cha
|
||||
if (so_far > MAX_RTPPRINTF_BUFFER_SIZE + 1) {
|
||||
so_far = MAX_RTPPRINTF_BUFFER_SIZE + 1;
|
||||
}
|
||||
if (!no_stdout_log)
|
||||
if (!no_stdout_log) {
|
||||
fwrite(s, so_far, 1, stdout);
|
||||
}
|
||||
/* write to syslog or to log file */
|
||||
if (to_syslog) {
|
||||
|
||||
@ -605,46 +622,62 @@ int get_default_protocol_port(const char *scheme, size_t slen) {
|
||||
if (scheme && (slen > 0)) {
|
||||
switch (slen) {
|
||||
case 3:
|
||||
if (!memcmp("ftp", scheme, 3))
|
||||
if (!memcmp("ftp", scheme, 3)) {
|
||||
return 21;
|
||||
if (!memcmp("svn", scheme, 3))
|
||||
}
|
||||
if (!memcmp("svn", scheme, 3)) {
|
||||
return 3690;
|
||||
if (!memcmp("ssh", scheme, 3))
|
||||
}
|
||||
if (!memcmp("ssh", scheme, 3)) {
|
||||
return 22;
|
||||
if (!memcmp("sip", scheme, 3))
|
||||
}
|
||||
if (!memcmp("sip", scheme, 3)) {
|
||||
return 5060;
|
||||
}
|
||||
break;
|
||||
case 4:
|
||||
if (!memcmp("http", scheme, 4))
|
||||
if (!memcmp("http", scheme, 4)) {
|
||||
return 80;
|
||||
if (!memcmp("ldap", scheme, 4))
|
||||
}
|
||||
if (!memcmp("ldap", scheme, 4)) {
|
||||
return 389;
|
||||
if (!memcmp("sips", scheme, 4))
|
||||
}
|
||||
if (!memcmp("sips", scheme, 4)) {
|
||||
return 5061;
|
||||
if (!memcmp("turn", scheme, 4))
|
||||
}
|
||||
if (!memcmp("turn", scheme, 4)) {
|
||||
return 3478;
|
||||
if (!memcmp("stun", scheme, 4))
|
||||
}
|
||||
if (!memcmp("stun", scheme, 4)) {
|
||||
return 3478;
|
||||
}
|
||||
break;
|
||||
case 5:
|
||||
if (!memcmp("https", scheme, 5))
|
||||
if (!memcmp("https", scheme, 5)) {
|
||||
return 443;
|
||||
if (!memcmp("ldaps", scheme, 5))
|
||||
}
|
||||
if (!memcmp("ldaps", scheme, 5)) {
|
||||
return 636;
|
||||
if (!memcmp("turns", scheme, 5))
|
||||
}
|
||||
if (!memcmp("turns", scheme, 5)) {
|
||||
return 5349;
|
||||
if (!memcmp("stuns", scheme, 5))
|
||||
}
|
||||
if (!memcmp("stuns", scheme, 5)) {
|
||||
return 5349;
|
||||
}
|
||||
break;
|
||||
case 6:
|
||||
if (!memcmp("telnet", scheme, 6))
|
||||
if (!memcmp("telnet", scheme, 6)) {
|
||||
return 23;
|
||||
if (!memcmp("radius", scheme, 6))
|
||||
}
|
||||
if (!memcmp("radius", scheme, 6)) {
|
||||
return 1645;
|
||||
}
|
||||
break;
|
||||
case 7:
|
||||
if (!memcmp("svn+ssh", scheme, 7))
|
||||
if (!memcmp("svn+ssh", scheme, 7)) {
|
||||
return 22;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
@ -682,10 +715,11 @@ int get_canonic_origin(const char *o, char *co, int sz) {
|
||||
if (port < 1) {
|
||||
port = get_default_protocol_port(otmp, schlen);
|
||||
}
|
||||
if (port > 0)
|
||||
if (port > 0) {
|
||||
snprintf(otmp + schlen, sizeof(otmp) - schlen - 1, "://%s:%d", host, port);
|
||||
else
|
||||
} else {
|
||||
snprintf(otmp + schlen, sizeof(otmp) - schlen - 1, "://%s", host);
|
||||
}
|
||||
|
||||
{
|
||||
unsigned char *s = (unsigned char *)otmp + schlen + 3;
|
||||
|
||||
@ -41,6 +41,7 @@ void err(int eval, const char *format, ...);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "ns_turn_defs.h" // for turn_time_t
|
||||
#include "ns_turn_ioaddr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -30,11 +30,14 @@
|
||||
|
||||
#include "stun_buffer.h"
|
||||
|
||||
#include <string.h> // for memset
|
||||
|
||||
////////////////////// BUFFERS ///////////////////////////
|
||||
|
||||
int stun_init_buffer(stun_buffer *buf) {
|
||||
if (!buf)
|
||||
if (!buf) {
|
||||
return -1;
|
||||
}
|
||||
memset(buf->buf, 0, sizeof(buf->buf));
|
||||
buf->len = 0;
|
||||
buf->offset = 0;
|
||||
@ -43,8 +46,9 @@ int stun_init_buffer(stun_buffer *buf) {
|
||||
}
|
||||
|
||||
int stun_get_size(const stun_buffer *buf) {
|
||||
if (!buf)
|
||||
if (!buf) {
|
||||
return 0;
|
||||
}
|
||||
return sizeof(buf->buf);
|
||||
}
|
||||
|
||||
@ -62,43 +66,46 @@ void stun_tid_generate_in_message(stun_buffer *buf, stun_tid *id) {
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
static inline int is_channel_msg(const stun_buffer *buf) {
|
||||
static inline bool is_channel_msg(const stun_buffer *buf) {
|
||||
if (buf && buf->len > 0) {
|
||||
return is_channel_msg_str(buf->buf, (size_t)(buf->len));
|
||||
}
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
int stun_is_command_message(const stun_buffer *buf) {
|
||||
if (!buf || buf->len <= 0)
|
||||
return 0;
|
||||
else
|
||||
bool stun_is_command_message(const stun_buffer *buf) {
|
||||
if (!buf || buf->len <= 0) {
|
||||
return false;
|
||||
} else {
|
||||
return stun_is_command_message_str(buf->buf, (size_t)(buf->len));
|
||||
}
|
||||
}
|
||||
|
||||
int stun_is_request(const stun_buffer *buf) { return stun_is_request_str(buf->buf, (size_t)buf->len); }
|
||||
bool stun_is_request(const stun_buffer *buf) { return stun_is_request_str(buf->buf, (size_t)buf->len); }
|
||||
|
||||
int stun_is_success_response(const stun_buffer *buf) {
|
||||
bool stun_is_success_response(const stun_buffer *buf) {
|
||||
return stun_is_success_response_str(buf->buf, (size_t)(buf->len));
|
||||
}
|
||||
|
||||
int stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size) {
|
||||
bool stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size) {
|
||||
return stun_is_error_response_str(buf->buf, (size_t)(buf->len), err_code, err_msg, err_msg_size);
|
||||
}
|
||||
|
||||
int stun_is_response(const stun_buffer *buf) { return stun_is_response_str(buf->buf, (size_t)(buf->len)); }
|
||||
bool stun_is_response(const stun_buffer *buf) { return stun_is_response_str(buf->buf, (size_t)(buf->len)); }
|
||||
|
||||
int stun_is_indication(const stun_buffer *buf) {
|
||||
if (is_channel_msg(buf))
|
||||
return 0;
|
||||
bool stun_is_indication(const stun_buffer *buf) {
|
||||
if (is_channel_msg(buf)) {
|
||||
return false;
|
||||
}
|
||||
return IS_STUN_INDICATION(stun_get_msg_type(buf));
|
||||
}
|
||||
|
||||
uint16_t stun_get_method(const stun_buffer *buf) { return stun_get_method_str(buf->buf, (size_t)(buf->len)); }
|
||||
|
||||
uint16_t stun_get_msg_type(const stun_buffer *buf) {
|
||||
if (!buf)
|
||||
if (!buf) {
|
||||
return (uint16_t)-1;
|
||||
}
|
||||
return stun_get_msg_type_str(buf->buf, (size_t)buf->len);
|
||||
}
|
||||
|
||||
@ -106,7 +113,7 @@ uint16_t stun_get_msg_type(const stun_buffer *buf) {
|
||||
|
||||
static void stun_init_command(uint16_t message_type, stun_buffer *buf) {
|
||||
buf->len = stun_get_size(buf);
|
||||
stun_init_command_str(message_type, buf->buf, (size_t *)(&(buf->len)));
|
||||
stun_init_command_str(message_type, buf->buf, &(buf->len));
|
||||
}
|
||||
|
||||
void stun_init_request(uint16_t method, stun_buffer *buf) { stun_init_command(stun_make_request(method), buf); }
|
||||
@ -115,32 +122,33 @@ void stun_init_indication(uint16_t method, stun_buffer *buf) { stun_init_command
|
||||
|
||||
void stun_init_success_response(uint16_t method, stun_buffer *buf, stun_tid *id) {
|
||||
buf->len = stun_get_size(buf);
|
||||
stun_init_success_response_str(method, buf->buf, (size_t *)(&(buf->len)), id);
|
||||
stun_init_success_response_str(method, buf->buf, &(buf->len), id);
|
||||
}
|
||||
|
||||
void stun_init_error_response(uint16_t method, stun_buffer *buf, uint16_t error_code, const uint8_t *reason,
|
||||
stun_tid *id) {
|
||||
buf->len = stun_get_size(buf);
|
||||
stun_init_error_response_str(method, buf->buf, (size_t *)(&(buf->len)), error_code, reason, id);
|
||||
stun_init_error_response_str(method, buf->buf, &(buf->len), error_code, reason, id);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_get_command_message_len(const stun_buffer *buf) {
|
||||
return stun_get_command_message_len_str(buf->buf, (size_t)(buf->len));
|
||||
return stun_get_command_message_len_str(buf->buf, buf->len);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, int do_padding) {
|
||||
return stun_init_channel_message_str(chnumber, buf->buf, (size_t *)(&(buf->len)), length, do_padding);
|
||||
bool stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, bool do_padding) {
|
||||
return stun_init_channel_message_str(chnumber, buf->buf, &(buf->len), length, do_padding);
|
||||
}
|
||||
|
||||
int stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, int is_padding_mandatory) {
|
||||
if (!buf)
|
||||
return 0;
|
||||
size_t blen = (size_t)buf->len;
|
||||
int ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory);
|
||||
bool stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, bool is_padding_mandatory) {
|
||||
if (!buf) {
|
||||
return false;
|
||||
}
|
||||
size_t blen = buf->len;
|
||||
bool ret = stun_is_channel_message_str(buf->buf, &blen, chnumber, is_padding_mandatory);
|
||||
if (ret) {
|
||||
buf->len = blen;
|
||||
}
|
||||
@ -149,93 +157,85 @@ int stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, int is_padding
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile,
|
||||
const char *rt, int ep) {
|
||||
return stun_set_allocate_request_str(buf->buf, (size_t *)(&(buf->len)), lifetime, af4, af6, transport, mobile, rt,
|
||||
ep);
|
||||
bool stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, bool af4, bool af6, uint8_t transport, bool mobile,
|
||||
const char *rt, int ep) {
|
||||
return stun_set_allocate_request_str(buf->buf, &(buf->len), lifetime, af4, af6, transport, mobile, rt, ep);
|
||||
}
|
||||
|
||||
int stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason, uint64_t reservation_token,
|
||||
char *mobile_id) {
|
||||
bool stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason,
|
||||
uint64_t reservation_token, char *mobile_id) {
|
||||
|
||||
return stun_set_allocate_response_str(buf->buf, (size_t *)(&(buf->len)), tid, relayed_addr1, relayed_addr2,
|
||||
reflexive_addr, lifetime, max_lifetime, error_code, reason, reservation_token,
|
||||
mobile_id);
|
||||
return stun_set_allocate_response_str(buf->buf, &(buf->len), tid, relayed_addr1, relayed_addr2, reflexive_addr,
|
||||
lifetime, max_lifetime, error_code, reason, reservation_token, mobile_id);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
uint16_t stun_set_channel_bind_request(stun_buffer *buf, const ioa_addr *peer_addr, uint16_t channel_number) {
|
||||
|
||||
return stun_set_channel_bind_request_str(buf->buf, (size_t *)(&(buf->len)), peer_addr, channel_number);
|
||||
return stun_set_channel_bind_request_str(buf->buf, &(buf->len), peer_addr, channel_number);
|
||||
}
|
||||
|
||||
void stun_set_channel_bind_response(stun_buffer *buf, stun_tid *tid, int error_code, const uint8_t *reason) {
|
||||
stun_set_channel_bind_response_str(buf->buf, (size_t *)(&(buf->len)), tid, error_code, reason);
|
||||
stun_set_channel_bind_response_str(buf->buf, &(buf->len), tid, error_code, reason);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
stun_attr_ref stun_attr_get_first(const stun_buffer *buf) {
|
||||
return stun_attr_get_first_str(buf->buf, (size_t)(buf->len));
|
||||
}
|
||||
stun_attr_ref stun_attr_get_first(const stun_buffer *buf) { return stun_attr_get_first_str(buf->buf, buf->len); }
|
||||
|
||||
stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref prev) {
|
||||
return stun_attr_get_next_str(buf->buf, (size_t)(buf->len), prev);
|
||||
return stun_attr_get_next_str(buf->buf, buf->len, prev);
|
||||
}
|
||||
|
||||
int stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen) {
|
||||
return stun_attr_add_str(buf->buf, (size_t *)(&(buf->len)), attr, (const uint8_t *)avalue, alen);
|
||||
bool stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen) {
|
||||
return stun_attr_add_str(buf->buf, &(buf->len), attr, (const uint8_t *)avalue, alen);
|
||||
}
|
||||
|
||||
int stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber) {
|
||||
return stun_attr_add_channel_number_str(buf->buf, (size_t *)(&(buf->len)), chnumber);
|
||||
bool stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber) {
|
||||
return stun_attr_add_channel_number_str(buf->buf, &(buf->len), chnumber);
|
||||
}
|
||||
|
||||
int stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca) {
|
||||
return stun_attr_add_addr_str(buf->buf, (size_t *)(&(buf->len)), attr_type, ca);
|
||||
bool stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca) {
|
||||
return stun_attr_add_addr_str(buf->buf, &(buf->len), attr_type, ca);
|
||||
}
|
||||
|
||||
int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr) {
|
||||
|
||||
return stun_attr_get_addr_str(buf->buf, (size_t)(buf->len), attr, ca, default_addr);
|
||||
bool stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr) {
|
||||
return stun_attr_get_addr_str(buf->buf, buf->len, attr, ca, default_addr);
|
||||
}
|
||||
|
||||
int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr) {
|
||||
|
||||
return stun_attr_get_first_addr_str(buf->buf, (size_t)(buf->len), attr_type, ca, default_addr);
|
||||
bool stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr) {
|
||||
return stun_attr_get_first_addr_str(buf->buf, buf->len, attr_type, ca, default_addr);
|
||||
}
|
||||
|
||||
int stun_attr_add_even_port(stun_buffer *buf, uint8_t value) {
|
||||
if (value)
|
||||
bool stun_attr_add_even_port(stun_buffer *buf, uint8_t value) {
|
||||
if (value) {
|
||||
value = 0x80;
|
||||
}
|
||||
return stun_attr_add(buf, STUN_ATTRIBUTE_EVEN_PORT, (const char *)&value, 1);
|
||||
}
|
||||
|
||||
uint16_t stun_attr_get_first_channel_number(const stun_buffer *buf) {
|
||||
return stun_attr_get_first_channel_number_str(buf->buf, (size_t)(buf->len));
|
||||
return stun_attr_get_first_channel_number_str(buf->buf, buf->len);
|
||||
}
|
||||
|
||||
stun_attr_ref stun_attr_get_first_by_type(const stun_buffer *buf, uint16_t attr_type) {
|
||||
return stun_attr_get_first_by_type_str(buf->buf, (size_t)(buf->len), attr_type);
|
||||
return stun_attr_get_first_by_type_str(buf->buf, buf->len, attr_type);
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void stun_set_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); }
|
||||
|
||||
int stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code,
|
||||
const uint8_t *reason) {
|
||||
return stun_set_binding_response_str(buf->buf, (size_t *)(&(buf->len)), tid, reflexive_addr, error_code, reason, 0, 0,
|
||||
1);
|
||||
bool stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code,
|
||||
const uint8_t *reason) {
|
||||
return stun_set_binding_response_str(buf->buf, &(buf->len), tid, reflexive_addr, error_code, reason, 0, false, true);
|
||||
}
|
||||
|
||||
void stun_prepare_binding_request(stun_buffer *buf) { stun_set_binding_request_str(buf->buf, (size_t *)(&(buf->len))); }
|
||||
|
||||
int stun_is_binding_response(const stun_buffer *buf) {
|
||||
return stun_is_binding_response_str(buf->buf, (size_t)(buf->len));
|
||||
}
|
||||
bool stun_is_binding_response(const stun_buffer *buf) { return stun_is_binding_response_str(buf->buf, buf->len); }
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
@ -31,7 +31,10 @@
|
||||
#ifndef __TURN_STUN_BUF__
|
||||
#define __TURN_STUN_BUF__
|
||||
|
||||
#include "ns_turn_defs.h" // for uint16_t, uint8_t, uint32_t, size_t
|
||||
#include "ns_turn_ioaddr.h" // for ioa_addr
|
||||
#include "ns_turn_msg.h"
|
||||
#include "ns_turn_msg_defs.h" // for STUN_CHANNEL_HEADER_LENGTH
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -59,12 +62,12 @@ void stun_tid_from_message(const stun_buffer *buf, stun_tid *id);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_is_command_message(const stun_buffer *buf);
|
||||
int stun_is_request(const stun_buffer *buf);
|
||||
int stun_is_response(const stun_buffer *buf);
|
||||
int stun_is_success_response(const stun_buffer *buf);
|
||||
int stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size);
|
||||
int stun_is_indication(const stun_buffer *buf);
|
||||
bool stun_is_command_message(const stun_buffer *buf);
|
||||
bool stun_is_request(const stun_buffer *buf);
|
||||
bool stun_is_response(const stun_buffer *buf);
|
||||
bool stun_is_success_response(const stun_buffer *buf);
|
||||
bool stun_is_error_response(const stun_buffer *buf, int *err_code, uint8_t *err_msg, size_t err_msg_size);
|
||||
bool stun_is_indication(const stun_buffer *buf);
|
||||
uint16_t stun_get_method(const stun_buffer *buf);
|
||||
uint16_t stun_get_msg_type(const stun_buffer *buf);
|
||||
|
||||
@ -78,17 +81,17 @@ void stun_init_error_response(uint16_t method, stun_buffer *buf, uint16_t error_
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen);
|
||||
int stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber);
|
||||
int stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca);
|
||||
bool stun_attr_add(stun_buffer *buf, uint16_t attr, const char *avalue, int alen);
|
||||
bool stun_attr_add_channel_number(stun_buffer *buf, uint16_t chnumber);
|
||||
bool stun_attr_add_addr(stun_buffer *buf, uint16_t attr_type, const ioa_addr *ca);
|
||||
|
||||
stun_attr_ref stun_attr_get_first(const stun_buffer *buf);
|
||||
stun_attr_ref stun_attr_get_first_by_type(const stun_buffer *buf, uint16_t attr_type);
|
||||
stun_attr_ref stun_attr_get_next(const stun_buffer *buf, stun_attr_ref prev);
|
||||
int stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr);
|
||||
int stun_attr_add_even_port(stun_buffer *buf, uint8_t value);
|
||||
bool stun_attr_get_addr(const stun_buffer *buf, stun_attr_ref attr, ioa_addr *ca, const ioa_addr *default_addr);
|
||||
bool stun_attr_add_even_port(stun_buffer *buf, uint8_t value);
|
||||
|
||||
int stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr);
|
||||
bool stun_attr_get_first_addr(const stun_buffer *buf, uint16_t attr_type, ioa_addr *ca, const ioa_addr *default_addr);
|
||||
uint16_t stun_attr_get_first_channel_number(const stun_buffer *buf);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
@ -97,26 +100,26 @@ int stun_get_command_message_len(const stun_buffer *buf);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, int do_padding);
|
||||
int stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, int is_padding_madatory);
|
||||
bool stun_init_channel_message(uint16_t chnumber, stun_buffer *buf, int length, bool do_padding);
|
||||
bool stun_is_channel_message(stun_buffer *buf, uint16_t *chnumber, bool is_padding_madatory);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, int af4, int af6, uint8_t transport, int mobile,
|
||||
const char *rt, int ep);
|
||||
int stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason, uint64_t reservation_token,
|
||||
char *mobile_id);
|
||||
bool stun_set_allocate_request(stun_buffer *buf, uint32_t lifetime, bool af4, bool af6, uint8_t transport, bool mobile,
|
||||
const char *rt, int ep);
|
||||
bool stun_set_allocate_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason,
|
||||
uint64_t reservation_token, char *mobile_id);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
void stun_set_binding_request(stun_buffer *buf);
|
||||
int stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code,
|
||||
const uint8_t *reason);
|
||||
bool stun_set_binding_response(stun_buffer *buf, stun_tid *tid, const ioa_addr *reflexive_addr, int error_code,
|
||||
const uint8_t *reason);
|
||||
|
||||
void stun_prepare_binding_request(stun_buffer *buf);
|
||||
int stun_is_binding_response(const stun_buffer *buf);
|
||||
bool stun_is_binding_response(const stun_buffer *buf);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -113,8 +113,9 @@ static const char illoptstring[] = "unknown option -- %s";
|
||||
|
||||
static void _vwarnx(const char *fmt, va_list ap) {
|
||||
(void)fprintf(stderr, "%s: ", __progname);
|
||||
if (fmt != NULL)
|
||||
if (fmt != NULL) {
|
||||
(void)vfprintf(stderr, fmt, ap);
|
||||
}
|
||||
(void)fprintf(stderr, "\n");
|
||||
}
|
||||
|
||||
@ -162,10 +163,11 @@ static void permute_args(int panonopt_start, int panonopt_end, int opt_end, char
|
||||
cstart = panonopt_end + i;
|
||||
pos = cstart;
|
||||
for (j = 0; j < cyclelen; j++) {
|
||||
if (pos >= panonopt_end)
|
||||
if (pos >= panonopt_end) {
|
||||
pos -= nnonopts;
|
||||
else
|
||||
} else {
|
||||
pos += nopts;
|
||||
}
|
||||
swap = nargv[pos];
|
||||
/* LINTED const cast */
|
||||
((char **)nargv)[pos] = nargv[cstart];
|
||||
@ -200,13 +202,15 @@ static int parse_long_options(char *const *nargv, const char *options, const str
|
||||
/* argument found (--option=arg) */
|
||||
current_argv_len = has_equal - current_argv;
|
||||
has_equal++;
|
||||
} else
|
||||
} else {
|
||||
current_argv_len = strlen(current_argv);
|
||||
}
|
||||
|
||||
for (i = 0; long_options[i].name; i++) {
|
||||
/* find matching long option */
|
||||
if (strncmp(current_argv, long_options[i].name, current_argv_len))
|
||||
if (strncmp(current_argv, long_options[i].name, current_argv_len)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (strlen(long_options[i].name) == current_argv_len) {
|
||||
/* exact match */
|
||||
@ -218,38 +222,43 @@ static int parse_long_options(char *const *nargv, const char *options, const str
|
||||
* If this is a known short option, don't allow
|
||||
* a partial match of a single character.
|
||||
*/
|
||||
if (short_too && current_argv_len == 1)
|
||||
if (short_too && current_argv_len == 1) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (match == -1) /* partial match */
|
||||
if (match == -1) { /* partial match */
|
||||
match = i;
|
||||
else if (!IDENTICAL_INTERPRETATION(i, match))
|
||||
} else if (!IDENTICAL_INTERPRETATION(i, match)) {
|
||||
ambiguous = 1;
|
||||
}
|
||||
}
|
||||
if (ambiguous) {
|
||||
/* ambiguous abbreviation */
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(ambig, (int)current_argv_len, current_argv);
|
||||
}
|
||||
optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (match != -1) { /* option found */
|
||||
if (long_options[match].has_arg == no_argument && has_equal) {
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(noarg, (int)current_argv_len, current_argv);
|
||||
}
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
if (long_options[match].flag == NULL) {
|
||||
optopt = long_options[match].val;
|
||||
else
|
||||
} else {
|
||||
optopt = 0;
|
||||
}
|
||||
return (BADARG);
|
||||
}
|
||||
if (long_options[match].has_arg == required_argument || long_options[match].has_arg == optional_argument) {
|
||||
if (has_equal)
|
||||
if (has_equal) {
|
||||
optarg = has_equal;
|
||||
else if (long_options[match].has_arg == required_argument) {
|
||||
} else if (long_options[match].has_arg == required_argument) {
|
||||
/*
|
||||
* optional argument doesn't use next nargv
|
||||
*/
|
||||
@ -261,15 +270,17 @@ static int parse_long_options(char *const *nargv, const char *options, const str
|
||||
* Missing argument; leading ':' indicates no error
|
||||
* should be generated.
|
||||
*/
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(recargstring, current_argv);
|
||||
}
|
||||
/*
|
||||
* XXX: GNU sets optopt to val regardless of flag
|
||||
*/
|
||||
if (long_options[match].flag == NULL)
|
||||
if (long_options[match].flag == NULL) {
|
||||
optopt = long_options[match].val;
|
||||
else
|
||||
} else {
|
||||
optopt = 0;
|
||||
}
|
||||
--optind;
|
||||
return (BADARG);
|
||||
}
|
||||
@ -278,18 +289,21 @@ static int parse_long_options(char *const *nargv, const char *options, const str
|
||||
--optind;
|
||||
return (-1);
|
||||
}
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(illoptstring, current_argv);
|
||||
}
|
||||
optopt = 0;
|
||||
return (BADCH);
|
||||
}
|
||||
if (idx)
|
||||
if (idx) {
|
||||
*idx = match;
|
||||
}
|
||||
if (long_options[match].flag) {
|
||||
*long_options[match].flag = long_options[match].val;
|
||||
return (0);
|
||||
} else
|
||||
} else {
|
||||
return (long_options[match].val);
|
||||
}
|
||||
#undef IDENTICAL_INTERPRETATION
|
||||
}
|
||||
|
||||
@ -303,15 +317,17 @@ static int getopt_internal(int nargc, char *const *nargv, const char *options, c
|
||||
int optchar, short_too;
|
||||
static int posixly_correct = -1;
|
||||
|
||||
if (options == NULL)
|
||||
if (options == NULL) {
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX Some GNU programs (like cvs) set optind to 0 instead of
|
||||
* XXX using optreset. Work around this braindamage.
|
||||
*/
|
||||
if (optind == 0)
|
||||
if (optind == 0) {
|
||||
optind = optreset = 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Disable GNU extensions if POSIXLY_CORRECT is set or options
|
||||
@ -320,18 +336,22 @@ static int getopt_internal(int nargc, char *const *nargv, const char *options, c
|
||||
* CV, 2009-12-14: Check POSIXLY_CORRECT anew if optind == 0 or
|
||||
* optreset != 0 for GNU compatibility.
|
||||
*/
|
||||
if (posixly_correct == -1 || optreset != 0)
|
||||
if (posixly_correct == -1 || optreset != 0) {
|
||||
posixly_correct = (getenv("POSIXLY_CORRECT") != NULL);
|
||||
if (*options == '-')
|
||||
}
|
||||
if (*options == '-') {
|
||||
flags |= FLAG_ALLARGS;
|
||||
else if (posixly_correct || *options == '+')
|
||||
} else if (posixly_correct || *options == '+') {
|
||||
flags &= ~FLAG_PERMUTE;
|
||||
if (*options == '+' || *options == '-')
|
||||
}
|
||||
if (*options == '+' || *options == '-') {
|
||||
options++;
|
||||
}
|
||||
|
||||
optarg = NULL;
|
||||
if (optreset)
|
||||
if (optreset) {
|
||||
nonopt_start = nonopt_end = -1;
|
||||
}
|
||||
start:
|
||||
if (optreset || !*place) { /* update scanning pointer */
|
||||
optreset = 0;
|
||||
@ -369,9 +389,9 @@ start:
|
||||
return (-1);
|
||||
}
|
||||
/* do permutation */
|
||||
if (nonopt_start == -1)
|
||||
if (nonopt_start == -1) {
|
||||
nonopt_start = optind;
|
||||
else if (nonopt_end != -1) {
|
||||
} else if (nonopt_end != -1) {
|
||||
permute_args(nonopt_start, nonopt_end, optind, nargv);
|
||||
nonopt_start = optind - (nonopt_end - nonopt_start);
|
||||
nonopt_end = -1;
|
||||
@ -380,8 +400,9 @@ start:
|
||||
/* process next argument */
|
||||
goto start;
|
||||
}
|
||||
if (nonopt_start != -1 && nonopt_end == -1)
|
||||
if (nonopt_start != -1 && nonopt_end == -1) {
|
||||
nonopt_end = optind;
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have "-" do nothing, if "--" we are done.
|
||||
@ -410,10 +431,11 @@ start:
|
||||
*/
|
||||
if (long_options != NULL && place != nargv[optind] && (*place == '-' || (flags & FLAG_LONGONLY))) {
|
||||
short_too = 0;
|
||||
if (*place == '-')
|
||||
if (*place == '-') {
|
||||
place++; /* --foo long option */
|
||||
else if (*place != ':' && strchr(options, *place) != NULL)
|
||||
} else if (*place != ':' && strchr(options, *place) != NULL) {
|
||||
short_too = 1; /* could be short option too */
|
||||
}
|
||||
|
||||
optchar = parse_long_options(nargv, options, long_options, idx, short_too);
|
||||
if (optchar != -1) {
|
||||
@ -429,47 +451,55 @@ start:
|
||||
* options, return -1 (non-option) as per POSIX.
|
||||
* Otherwise, it is an unknown option character (or ':').
|
||||
*/
|
||||
if (optchar == (int)'-' && *place == '\0')
|
||||
if (optchar == (int)'-' && *place == '\0') {
|
||||
return (-1);
|
||||
if (!*place)
|
||||
}
|
||||
if (!*place) {
|
||||
++optind;
|
||||
if (PRINT_ERROR)
|
||||
}
|
||||
if (PRINT_ERROR) {
|
||||
warnx(illoptchar, optchar);
|
||||
}
|
||||
optopt = optchar;
|
||||
return (BADCH);
|
||||
}
|
||||
if (long_options != NULL && optchar == 'W' && oli[1] == ';') {
|
||||
/* -W long-option */
|
||||
if (*place) /* no space */
|
||||
if (*place) /* no space */ {
|
||||
/* NOTHING */;
|
||||
else if (++optind >= nargc) { /* no arg */
|
||||
} else if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(recargchar, optchar);
|
||||
}
|
||||
optopt = optchar;
|
||||
return (BADARG);
|
||||
} else /* white space */
|
||||
} else { /* white space */
|
||||
place = nargv[optind];
|
||||
}
|
||||
optchar = parse_long_options(nargv, options, long_options, idx, 0);
|
||||
place = EMSG;
|
||||
return (optchar);
|
||||
}
|
||||
if (*++oli != ':') { /* doesn't take argument */
|
||||
if (!*place)
|
||||
if (!*place) {
|
||||
++optind;
|
||||
}
|
||||
} else { /* takes (optional) argument */
|
||||
optarg = NULL;
|
||||
if (*place) /* no white space */
|
||||
if (*place) { /* no white space */
|
||||
optarg = place;
|
||||
else if (oli[1] != ':') { /* arg not optional */
|
||||
if (++optind >= nargc) { /* no arg */
|
||||
} else if (oli[1] != ':') { /* arg not optional */
|
||||
if (++optind >= nargc) { /* no arg */
|
||||
place = EMSG;
|
||||
if (PRINT_ERROR)
|
||||
if (PRINT_ERROR) {
|
||||
warnx(recargchar, optchar);
|
||||
}
|
||||
optopt = optchar;
|
||||
return (BADARG);
|
||||
} else
|
||||
} else {
|
||||
optarg = nargv[optind];
|
||||
}
|
||||
}
|
||||
place = EMSG;
|
||||
++optind;
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -40,6 +41,7 @@
|
||||
#endif
|
||||
|
||||
#include "apputils.h"
|
||||
#include "ns_turn_ioalib.h"
|
||||
#include "ns_turn_utils.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
@ -63,19 +65,21 @@ static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_
|
||||
}
|
||||
|
||||
*socketfd = socket(remote_addr->ss.sa_family, SOCK_DGRAM, 0);
|
||||
if (udp_fd < 0)
|
||||
if (udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (!addr_any(local_addr)) {
|
||||
if (addr_bind(*socketfd, local_addr, 0, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(*socketfd, local_addr, 0, 1, UDP_SOCKET) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, int change_ip,
|
||||
int change_port, int padding, int response_port) {
|
||||
static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr, bool change_ip,
|
||||
bool change_port, int padding, int response_port) {
|
||||
int ret = 0;
|
||||
|
||||
turn::StunMsgRequest req(STUN_METHOD_BINDING);
|
||||
@ -140,8 +144,9 @@ static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, io
|
||||
len = sendto(sockfd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr *)remote_addr, (socklen_t)slen);
|
||||
} while (len < 0 && (socket_eintr() || socket_enobufs() || socket_eagain()));
|
||||
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr_get_from_sock(sockfd, local_addr) < 0) {
|
||||
@ -154,7 +159,7 @@ static int stunclient_send(int sockfd, ioa_addr *local_addr, int *local_port, io
|
||||
}
|
||||
|
||||
static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr,
|
||||
int *rfc5780) {
|
||||
bool *rfc5780) {
|
||||
int ret = 0;
|
||||
|
||||
{
|
||||
@ -184,8 +189,9 @@ static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflex
|
||||
ret = 1;
|
||||
return ret;
|
||||
}
|
||||
if (recvd > 0)
|
||||
if (recvd > 0) {
|
||||
len = recvd;
|
||||
}
|
||||
buf.len = len;
|
||||
|
||||
try {
|
||||
@ -204,7 +210,7 @@ static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflex
|
||||
|
||||
turn::StunAttrIterator iter1(res, STUN_ATTRIBUTE_OTHER_ADDRESS);
|
||||
if (!iter1.eof()) {
|
||||
*rfc5780 = 1;
|
||||
*rfc5780 = true;
|
||||
printf("\n========================================\n");
|
||||
printf("RFC 5780 response %d\n", ++counter);
|
||||
turn::StunAttrIterator iter2(res, STUN_ATTRIBUTE_MAPPED_ADDRESS);
|
||||
@ -266,7 +272,7 @@ static int stunclient_receive(int sockfd, ioa_addr *local_addr, ioa_addr *reflex
|
||||
}
|
||||
|
||||
static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr,
|
||||
int *local_port, int *rfc5780, int change_ip, int change_port, int padding) {
|
||||
int *local_port, bool *rfc5780, bool change_ip, bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
|
||||
ret = init_socket(&udp_fd, local_addr, *local_port, remote_addr);
|
||||
@ -278,8 +284,8 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr
|
||||
}
|
||||
|
||||
static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr,
|
||||
ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip,
|
||||
int change_port, int padding) {
|
||||
ioa_addr *other_addr, int *local_port, bool *rfc5780, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
|
||||
init_socket(&udp_fd, local_addr, *local_port, remote_addr);
|
||||
@ -305,8 +311,8 @@ static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_add
|
||||
}
|
||||
|
||||
static int run_stunclient_lifetime(int timer, ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr,
|
||||
ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port,
|
||||
int padding) {
|
||||
ioa_addr *other_addr, int *local_port, bool *rfc5780, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
int response_port;
|
||||
|
||||
@ -336,8 +342,9 @@ static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_
|
||||
int ret = 0;
|
||||
|
||||
*socketfd = socket(remote_addr->ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
|
||||
if (udp_fd < 0)
|
||||
if (udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (local_port >= 0) {
|
||||
addr_set_port(local_addr, local_port);
|
||||
@ -352,7 +359,7 @@ static int init_socket(int *socketfd, ioa_addr *local_addr, int local_port, ioa_
|
||||
}
|
||||
|
||||
static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, int *local_port, ioa_addr *remote_addr,
|
||||
int change_ip, int change_port, int padding, int response_port) {
|
||||
bool change_ip, bool change_port, int padding, int response_port) {
|
||||
int ret = 0;
|
||||
|
||||
stun_prepare_binding_request(buf);
|
||||
@ -364,7 +371,7 @@ static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, i
|
||||
stun_attr_add_change_request_str((uint8_t *)buf->buf, (size_t *)&(buf->len), change_ip, change_port);
|
||||
}
|
||||
if (padding) {
|
||||
if (stun_attr_add_padding_str((uint8_t *)buf->buf, (size_t *)&(buf->len), 1500) < 0) {
|
||||
if (!stun_attr_add_padding_str((uint8_t *)buf->buf, (size_t *)&(buf->len), 1500)) {
|
||||
printf("%s: ERROR: Cannot add padding\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
@ -377,8 +384,9 @@ static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, i
|
||||
len = sendto(sockfd, buf->buf, buf->len, 0, (struct sockaddr *)remote_addr, (socklen_t)slen);
|
||||
} while (len < 0 && (socket_eintr() || socket_enobufs() || socket_eagain()));
|
||||
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr_get_from_sock(sockfd, local_addr) < 0) {
|
||||
@ -391,7 +399,7 @@ static int stunclient_send(stun_buffer *buf, int sockfd, ioa_addr *local_addr, i
|
||||
}
|
||||
|
||||
static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr, ioa_addr *reflexive_addr,
|
||||
ioa_addr *other_addr, int *rfc5780) {
|
||||
ioa_addr *other_addr, bool *rfc5780) {
|
||||
int ret = 0;
|
||||
|
||||
{
|
||||
@ -415,8 +423,9 @@ static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr
|
||||
}
|
||||
} while (len < 0 && socket_eintr());
|
||||
|
||||
if (recvd > 0)
|
||||
if (recvd > 0) {
|
||||
len = recvd;
|
||||
}
|
||||
buf->len = len;
|
||||
|
||||
if (stun_is_command_message(buf)) {
|
||||
@ -428,16 +437,15 @@ static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr
|
||||
if (stun_is_binding_response(buf)) {
|
||||
|
||||
addr_set_any(reflexive_addr);
|
||||
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL) >= 0) {
|
||||
|
||||
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr, NULL)) {
|
||||
stun_attr_ref sar = stun_attr_get_first_by_type_str(buf->buf, buf->len, STUN_ATTRIBUTE_OTHER_ADDRESS);
|
||||
if (sar) {
|
||||
*rfc5780 = 1;
|
||||
*rfc5780 = true;
|
||||
printf("\n========================================\n");
|
||||
printf("RFC 5780 response %d\n", ++counter);
|
||||
ioa_addr mapped_addr;
|
||||
addr_set_any(&mapped_addr);
|
||||
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL) >= 0) {
|
||||
if (stun_attr_get_first_addr(buf, STUN_ATTRIBUTE_MAPPED_ADDRESS, &mapped_addr, NULL)) {
|
||||
if (!addr_eq(&mapped_addr, reflexive_addr)) {
|
||||
printf("-= ALG detected! Mapped and XOR-Mapped differ! =-\n");
|
||||
addr_debug_print(1, &mapped_addr, "Mapped Address: ");
|
||||
@ -494,7 +502,7 @@ static int stunclient_receive(stun_buffer *buf, int sockfd, ioa_addr *local_addr
|
||||
}
|
||||
|
||||
static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr, ioa_addr *other_addr,
|
||||
int *local_port, int *rfc5780, int change_ip, int change_port, int padding) {
|
||||
int *local_port, bool *rfc5780, bool change_ip, bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
stun_buffer buf;
|
||||
|
||||
@ -509,8 +517,8 @@ static int run_stunclient(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr
|
||||
}
|
||||
|
||||
static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr,
|
||||
ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip,
|
||||
int change_port, int padding) {
|
||||
ioa_addr *other_addr, int *local_port, bool *rfc5780, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
stun_buffer buf;
|
||||
stun_buffer buf2;
|
||||
@ -539,8 +547,8 @@ static int run_stunclient_hairpinning(ioa_addr *local_addr, ioa_addr *remote_add
|
||||
}
|
||||
|
||||
static int run_stunclient_lifetime(int timer, ioa_addr *local_addr, ioa_addr *remote_addr, ioa_addr *reflexive_addr,
|
||||
ioa_addr *other_addr, int *local_port, int *rfc5780, int change_ip, int change_port,
|
||||
int padding) {
|
||||
ioa_addr *other_addr, int *local_port, bool *rfc5780, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
int ret = 0;
|
||||
stun_buffer buf;
|
||||
stun_buffer buf2;
|
||||
@ -592,7 +600,7 @@ static char Usage[] = "Usage: natdiscovery [options] address\n"
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *local_port, int port, int *rfc5780,
|
||||
static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *local_port, int port, bool *rfc5780,
|
||||
char *local_addr_string, char *remote_param) {
|
||||
addr_set_any(local_addr);
|
||||
|
||||
@ -601,12 +609,14 @@ static void init(int first, ioa_addr *local_addr, ioa_addr *remote_addr, int *lo
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
if (!first)
|
||||
if (!first) {
|
||||
*local_port = -1;
|
||||
*rfc5780 = 0;
|
||||
}
|
||||
*rfc5780 = false;
|
||||
|
||||
if (make_ioa_addr((const uint8_t *)remote_param, port, remote_addr) < 0)
|
||||
if (make_ioa_addr((const uint8_t *)remote_param, port, remote_addr) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
static void discoveryresult(const char *decision) {
|
||||
@ -617,8 +627,8 @@ static void discoveryresult(const char *decision) {
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
int remote_port = DEFAULT_STUN_PORT;
|
||||
char local_addr_string[256] = "\0";
|
||||
char local2_addr_string[256] = "\0";
|
||||
char local_addr_string[256] = {0};
|
||||
char local2_addr_string[256] = {0};
|
||||
int c = 0;
|
||||
int mapping = 0;
|
||||
int filtering = 0;
|
||||
@ -628,19 +638,18 @@ int main(int argc, char **argv) {
|
||||
int padding = 0;
|
||||
int hairpinning = 0;
|
||||
int local_port = -1;
|
||||
int rfc5780;
|
||||
bool rfc5780;
|
||||
int first = 1;
|
||||
ioa_addr other_addr, reflexive_addr, tmp_addr, remote_addr, local_addr, local2_addr;
|
||||
|
||||
if (socket_init())
|
||||
if (socket_init()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_logfile("stdout");
|
||||
set_no_stdout_log(1);
|
||||
set_system_parameters(0);
|
||||
|
||||
memset(local_addr_string, 0, sizeof(local_addr_string));
|
||||
memset(local2_addr_string, 0, sizeof(local2_addr_string));
|
||||
addr_set_any(&remote_addr);
|
||||
addr_set_any(&other_addr);
|
||||
addr_set_any(&reflexive_addr);
|
||||
|
||||
@ -28,6 +28,14 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "ns_turn_defs.h" // for STRCPY, turn_time_t, uint8_t, uint32_t
|
||||
#include "ns_turn_msg.h" // for convert_oauth_key_data, decode_oauth_t...
|
||||
#include "ns_turn_msg_defs.h" // for oauth_token, oauth_encrypted_block
|
||||
#include "ns_turn_utils.h"
|
||||
|
||||
#include "apputils.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
#if defined(__unix__)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
@ -39,10 +47,6 @@
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "apputils.h"
|
||||
#include "ns_turn_utils.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
////////////////////////////////////////////////////
|
||||
|
||||
#define OAUTH_TOKEN_SIZE 1000 // TODO: find insted of 1000 the real max of encoded token length
|
||||
@ -80,7 +84,7 @@ static int setup_ikm_key(const char *kid, const char *ikm_key, const turn_time_t
|
||||
char err_msg[1025] = "\0";
|
||||
size_t err_msg_size = sizeof(err_msg) - 1;
|
||||
|
||||
if (convert_oauth_key_data(&okd, key, err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd, key, err_msg, err_msg_size)) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
return -1;
|
||||
}
|
||||
@ -105,10 +109,11 @@ static int encode_token(const char *server_name, const char *gcm_nonce, const ch
|
||||
memset(&etoken, 0, sizeof(etoken));
|
||||
|
||||
// TODO: avoid this hack
|
||||
if (!*gcm_nonce)
|
||||
if (!*gcm_nonce) {
|
||||
gcm_nonce = NULL;
|
||||
}
|
||||
|
||||
if (encode_oauth_token((const uint8_t *)server_name, &etoken, &key, &ot, (const uint8_t *)gcm_nonce) < 0) {
|
||||
if (!encode_oauth_token((const uint8_t *)server_name, &etoken, &key, &ot, (const uint8_t *)gcm_nonce)) {
|
||||
fprintf(stderr, "%s: cannot encode oauth token\n", __FUNCTION__);
|
||||
return -1;
|
||||
}
|
||||
@ -124,7 +129,7 @@ static int encode_token(const char *server_name, const char *gcm_nonce, const ch
|
||||
static int validate_decode_token(const char *server_name, const oauth_key key, const char *base64encoded_etoken,
|
||||
oauth_token *dot) {
|
||||
|
||||
memset((dot), 0, sizeof(*dot));
|
||||
memset(dot, 0, sizeof(*dot));
|
||||
|
||||
encoded_oauth_token etoken;
|
||||
memset(&etoken, 0, sizeof(etoken));
|
||||
@ -134,7 +139,7 @@ static int validate_decode_token(const char *server_name, const oauth_key key, c
|
||||
memcpy(etoken.token, tmp, etoken.size);
|
||||
free(tmp);
|
||||
|
||||
if (decode_oauth_token((const uint8_t *)server_name, &etoken, &key, dot) < 0) {
|
||||
if (!decode_oauth_token((const uint8_t *)server_name, &etoken, &key, dot)) {
|
||||
fprintf(stderr, "%s: cannot decode oauth token\n", __FUNCTION__);
|
||||
return -1;
|
||||
} else {
|
||||
@ -370,8 +375,9 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
}
|
||||
|
||||
for (i = optind; i < argc; i++)
|
||||
for (i = optind; i < argc; i++) {
|
||||
printf("Non-option argument %s\n", argv[i]);
|
||||
}
|
||||
|
||||
if (optind > argc) {
|
||||
fprintf(stderr, "%s\n", Usage);
|
||||
@ -456,8 +462,9 @@ int main(int argc, char **argv) {
|
||||
oauth_token dot;
|
||||
if (validate_decode_token(server_name, key, base64encoded_etoken, &dot) == 0) {
|
||||
printf("-=Valid token!=-\n");
|
||||
if (verbose_flag)
|
||||
if (verbose_flag) {
|
||||
print_token_body(&dot);
|
||||
}
|
||||
} else {
|
||||
fprintf(stderr, "Error during token validation and decoding\n");
|
||||
exit(-1);
|
||||
|
||||
@ -61,8 +61,9 @@ int main(int argc, char **argv) {
|
||||
int c;
|
||||
char ifname[1025] = "\0";
|
||||
|
||||
if (socket_init())
|
||||
if (socket_init()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
IS_TURN_SERVER = 1;
|
||||
|
||||
@ -70,7 +71,7 @@ int main(int argc, char **argv) {
|
||||
set_no_stdout_log(1);
|
||||
set_system_parameters(0);
|
||||
|
||||
while ((c = getopt(argc, argv, "d:p:L:v")) != -1)
|
||||
while ((c = getopt(argc, argv, "d:p:L:v")) != -1) {
|
||||
switch (c) {
|
||||
case 'd':
|
||||
STRCPY(ifname, optarg);
|
||||
@ -89,6 +90,7 @@ int main(int argc, char **argv) {
|
||||
fprintf(stderr, "%s\n", Usage);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
if (las < 1) {
|
||||
local_addr_list = (char **)realloc(local_addr_list, ++las * sizeof(char *));
|
||||
|
||||
@ -32,12 +32,15 @@
|
||||
#include "apputils.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
#include <limits.h> // for USHRT_MAX
|
||||
|
||||
/////////////// io handlers ///////////////////
|
||||
|
||||
static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) {
|
||||
|
||||
if (!(what & EV_READ))
|
||||
if (!(what & EV_READ)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ioa_addr *addr = (ioa_addr *)arg;
|
||||
|
||||
@ -61,23 +64,30 @@ static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg)
|
||||
|
||||
///////////////////// operations //////////////////////////
|
||||
|
||||
static int udp_create_server_socket(server_type *server, const char *ifname, const char *local_address, int port) {
|
||||
static int udp_create_server_socket(server_type *const server, const char *const ifname,
|
||||
const char *const local_address, int const port) {
|
||||
|
||||
if (server && server->verbose)
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n");
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (server->verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Start\n");
|
||||
}
|
||||
|
||||
evutil_socket_t udp_fd = -1;
|
||||
ioa_addr *server_addr = (ioa_addr *)malloc(sizeof(ioa_addr));
|
||||
if (!server_addr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
STRCPY(server->ifname, ifname);
|
||||
|
||||
if (make_ioa_addr((const uint8_t *)local_address, port, server_addr) < 0)
|
||||
if (make_ioa_addr((const uint8_t *)local_address, port, server_addr) < 0) {
|
||||
free(server_addr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
udp_fd = socket(server_addr->ss.sa_family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL);
|
||||
evutil_socket_t udp_fd = socket(server_addr->ss.sa_family, RELAY_DGRAM_SOCKET_TYPE, RELAY_DGRAM_SOCKET_PROTOCOL);
|
||||
if (udp_fd < 0) {
|
||||
perror("socket");
|
||||
free(server_addr);
|
||||
@ -90,8 +100,9 @@ static int udp_create_server_socket(server_type *server, const char *ifname, con
|
||||
|
||||
set_sock_buf_size(udp_fd, UR_SERVER_SOCK_BUF_SIZE);
|
||||
|
||||
if (addr_bind(udp_fd, server_addr, 1, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(udp_fd, server_addr, 1, 1, UDP_SOCKET) < 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
socket_set_nonblocking(udp_fd);
|
||||
|
||||
@ -100,23 +111,26 @@ static int udp_create_server_socket(server_type *server, const char *ifname, con
|
||||
|
||||
event_add(udp_ev, NULL);
|
||||
|
||||
if (server && server->verbose)
|
||||
if (server->verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "End\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static server_type *init_server(int verbose, const char *ifname, char **local_addresses, size_t las, int port) {
|
||||
|
||||
server_type *server = (server_type *)malloc(sizeof(server_type));
|
||||
|
||||
if (!server)
|
||||
return server;
|
||||
|
||||
memset(server, 0, sizeof(server_type));
|
||||
// Ports cannot be larger than unsigned 16 bits
|
||||
// and since this function creates two ports next to each other
|
||||
// the provided port must be smaller than max unsigned 16.
|
||||
if ((uint16_t)port >= USHRT_MAX) {
|
||||
return NULL;
|
||||
}
|
||||
server_type *server = (server_type *)calloc(1, sizeof(server_type));
|
||||
if (!server) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
server->verbose = verbose;
|
||||
|
||||
server->event_base = turn_event_base_new();
|
||||
|
||||
while (las) {
|
||||
@ -129,8 +143,9 @@ static server_type *init_server(int verbose, const char *ifname, char **local_ad
|
||||
|
||||
static int clean_server(server_type *server) {
|
||||
if (server) {
|
||||
if (server->event_base)
|
||||
if (server->event_base) {
|
||||
event_base_free(server->event_base);
|
||||
}
|
||||
free(server);
|
||||
}
|
||||
return 0;
|
||||
@ -140,8 +155,9 @@ static int clean_server(server_type *server) {
|
||||
|
||||
static void run_events(server_type *server) {
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
@ -161,21 +177,16 @@ server_type *start_udp_server(int verbose, const char *ifname, char **local_addr
|
||||
void run_udp_server(server_type *server) {
|
||||
|
||||
if (server) {
|
||||
|
||||
unsigned int cycle = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
cycle++;
|
||||
|
||||
run_events(server);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void clean_udp_server(server_type *server) {
|
||||
if (server)
|
||||
if (server) {
|
||||
clean_server(server);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -37,6 +37,8 @@
|
||||
|
||||
#include <event2/event.h>
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
@ -75,7 +75,7 @@ else()
|
||||
list(APPEND turnserver_DEFINED TURN_NO_MYSQL)
|
||||
endif()
|
||||
|
||||
if(WIN32)
|
||||
if(WIN32 OR APPLE)
|
||||
find_package(mongoc-1.0)
|
||||
if(mongoc-1.0_FOUND)
|
||||
list(APPEND turnserver_LIBS mongo::mongoc_shared)
|
||||
@ -87,24 +87,24 @@ if(WIN32)
|
||||
else()
|
||||
find_package(mongo)
|
||||
if(mongo_FOUND)
|
||||
list(APPEND turnserver_LIBS mongo)
|
||||
list(APPEND SOURCE_FILES dbdrivers/dbd_mongo.c)
|
||||
list(APPEND turnserver_LIBS mongo)
|
||||
list(APPEND SOURCE_FILES dbdrivers/dbd_mongo.c)
|
||||
list(APPEND HEADER_FILES dbdrivers/dbd_mongo.h)
|
||||
else()
|
||||
list(APPEND turnserver_DEFINED TURN_NO_MONGO)
|
||||
list(APPEND turnserver_DEFINED TURN_NO_MONGO)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
find_package(hiredis)
|
||||
if(hiredis_FOUND)
|
||||
list(APPEND turnserver_LIBS hiredis::hiredis)
|
||||
list(APPEND SOURCE_FILES dbdrivers/dbd_redis.c)
|
||||
list(APPEND HEADER_FILES dbdrivers/dbd_redis.h)
|
||||
pkg_check_modules(HIREDIS IMPORTED_TARGET hiredis)
|
||||
if(HIREDIS_FOUND)
|
||||
list(APPEND turnserver_LIBS PkgConfig::HIREDIS)
|
||||
list(APPEND SOURCE_FILES hiredis_libevent2.c dbdrivers/dbd_redis.c)
|
||||
list(APPEND HEADER_FILES hiredis_libevent2.h dbdrivers/dbd_redis.h)
|
||||
else()
|
||||
list(APPEND turnserver_DEFINED TURN_NO_HIREDIS)
|
||||
endif()
|
||||
|
||||
if(UNIX)
|
||||
if(UNIX AND (NOT APPLE))
|
||||
find_package(libsystemd)
|
||||
if(NOT libsystemd_FOUND)
|
||||
list(APPEND turnserver_DEFINED TURN_NO_SYSTEMD)
|
||||
@ -118,8 +118,8 @@ if(Prometheus_FOUND)
|
||||
list(APPEND turnserver_LIBS ${Prometheus_LIBRARIES})
|
||||
list(APPEND turnserver_include_dirs ${Prometheus_INCLUDE_DIRS})
|
||||
else()
|
||||
message(AUTHOR_WARNING "Don't find prometheus. please install "
|
||||
"prom, promhttp, microhttpd, and set Prometheus_ROOT. "
|
||||
message(AUTHOR_WARNING "Could not find prometheus. Please install "
|
||||
"prom, microhttpd, and set Prometheus_ROOT. "
|
||||
"See docs/Prometheus.md")
|
||||
list(APPEND turnserver_DEFINED TURN_NO_PROMETHEUS)
|
||||
endif()
|
||||
|
||||
@ -8,6 +8,10 @@
|
||||
#include "acme.h"
|
||||
#include "ns_ioalib_impl.h"
|
||||
|
||||
#if !defined(_MSC_VER)
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#define GET_ACME_PREFIX "GET /.well-known/acme-challenge/"
|
||||
#define GET_ACME_PREFIX_LEN 32
|
||||
|
||||
@ -17,26 +21,31 @@ static int is_acme_req(char *req, size_t len) {
|
||||
int c, i, k;
|
||||
|
||||
// Check first request line. Should be like: GET path HTTP/1.x
|
||||
if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN))
|
||||
if (strncmp(req, GET_ACME_PREFIX, GET_ACME_PREFIX_LEN)) {
|
||||
return -1;
|
||||
}
|
||||
// Usually (for LE) the "method path" is 32 + 43 = 55 chars. But other
|
||||
// implementations may choose longer pathes. We define PATHMAX = 127 chars
|
||||
// to be prepared for "DoS" attacks (STUN msg size max. is ~ 64K).
|
||||
len -= 21; // min size of trailing headers
|
||||
if (len > 131)
|
||||
if (len > 131) {
|
||||
len = 131;
|
||||
}
|
||||
for (i = GET_ACME_PREFIX_LEN; i < (int)len; i++) {
|
||||
// find the end of the path
|
||||
if (req[i] != ' ')
|
||||
if (req[i] != ' ') {
|
||||
continue;
|
||||
}
|
||||
// consider path < 10 chars invalid. Also we wanna see a "trailer".
|
||||
if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8))
|
||||
if (i < (GET_ACME_PREFIX_LEN + 10) || strncmp(req + i, " HTTP/1.", 8)) {
|
||||
return -2;
|
||||
}
|
||||
// finally check for allowed chars
|
||||
for (k = GET_ACME_PREFIX_LEN; k < i; k++) {
|
||||
c = req[k];
|
||||
if ((c > 127) || (A[c] == ' '))
|
||||
if ((c > 127) || (A[c] == ' ')) {
|
||||
return -3;
|
||||
}
|
||||
}
|
||||
// all checks passed: sufficient for us to answer with a redirect
|
||||
return i;
|
||||
@ -50,11 +59,13 @@ int try_acme_redirect(char *req, size_t len, const char *url, ioa_socket_handle
|
||||
char http_response[1024];
|
||||
size_t plen, rlen;
|
||||
|
||||
if (url == NULL || url[0] == '\0' || req == NULL || s == 0)
|
||||
if (url == NULL || url[0] == '\0' || req == NULL || s == 0) {
|
||||
return 1;
|
||||
}
|
||||
if (len < (GET_ACME_PREFIX_LEN + 32) || len > (512 - GET_ACME_PREFIX_LEN) ||
|
||||
(plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1))
|
||||
(plen = is_acme_req(req, len)) < (GET_ACME_PREFIX_LEN + 1)) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
req[plen] = '\0';
|
||||
|
||||
|
||||
@ -72,10 +72,12 @@ static void mongo_logger(mongoc_log_level_t log_level, const char *log_domain, c
|
||||
|
||||
static void MongoFree(MONGO *info) {
|
||||
if (info) {
|
||||
if (info->uri)
|
||||
if (info->uri) {
|
||||
mongoc_uri_destroy(info->uri);
|
||||
if (info->client)
|
||||
}
|
||||
if (info->client) {
|
||||
mongoc_client_destroy(info->client);
|
||||
}
|
||||
free(info);
|
||||
}
|
||||
}
|
||||
@ -90,8 +92,7 @@ static MONGO *get_mongodb_connection(void) {
|
||||
mongoc_init();
|
||||
mongoc_log_set_handler(&mongo_logger, NULL);
|
||||
|
||||
mydbconnection = (MONGO *)malloc(sizeof(MONGO));
|
||||
memset(mydbconnection, 0, sizeof(MONGO));
|
||||
mydbconnection = (MONGO *)calloc(1, sizeof(MONGO));
|
||||
|
||||
mydbconnection->uri = mongoc_uri_new(pud->userdb);
|
||||
|
||||
@ -108,8 +109,9 @@ static MONGO *get_mongodb_connection(void) {
|
||||
mydbconnection = NULL;
|
||||
} else {
|
||||
mydbconnection->database = mongoc_uri_get_database(mydbconnection->uri);
|
||||
if (!mydbconnection->database)
|
||||
if (!mydbconnection->database) {
|
||||
mydbconnection->database = MONGO_DEFAULT_DB;
|
||||
}
|
||||
if (mydbconnection) {
|
||||
(void)pthread_setspecific(connection_key, mydbconnection);
|
||||
}
|
||||
@ -143,8 +145,9 @@ static mongoc_collection_t *mongo_get_collection(const char *name) {
|
||||
static int mongo_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turn_secret");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -185,8 +188,9 @@ static int mongo_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) {
|
||||
static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turnusers_lt");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -220,11 +224,8 @@ static int mongo_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
char kval[sizeof(hmackey_t) + sizeof(hmackey_t) + 1];
|
||||
memcpy(kval, value, sz);
|
||||
kval[sz] = 0;
|
||||
if (convert_string_key_to_binary(kval, key, sz / 2) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
convert_string_key_to_binary(kval, key, sz / 2);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -240,8 +241,9 @@ static int mongo_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) {
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("oauth_key");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -298,8 +300,9 @@ static int mongo_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) {
|
||||
static int mongo_set_user_key(uint8_t *usname, uint8_t *realm, const char *key) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turnusers_lt");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -329,8 +332,9 @@ static int mongo_set_oauth_key(oauth_key_data_raw *key) {
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("oauth_key");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -361,8 +365,9 @@ static int mongo_set_oauth_key(oauth_key_data_raw *key) {
|
||||
static int mongo_del_user(uint8_t *usname, uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turnusers_lt");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -385,8 +390,9 @@ static int mongo_del_oauth_key(const uint8_t *kid) {
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("oauth_key");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -409,11 +415,13 @@ static int mongo_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
mongoc_collection_t *collection = mongo_get_collection(collection_name);
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query, child;
|
||||
bson_init(&query);
|
||||
@ -484,8 +492,9 @@ static int mongo_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, sec
|
||||
const char *collection_name = "oauth_key";
|
||||
mongoc_collection_t *collection = mongo_get_collection(collection_name);
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -572,11 +581,13 @@ static int mongo_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
mongoc_collection_t *collection = mongo_get_collection("turn_secret");
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query, child;
|
||||
bson_init(&query);
|
||||
@ -644,8 +655,9 @@ static int mongo_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
static int mongo_del_secret(uint8_t *secret, uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turn_secret");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -663,8 +675,9 @@ static int mongo_del_secret(uint8_t *secret, uint8_t *realm) {
|
||||
static int mongo_set_secret(uint8_t *secret, uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("turn_secret");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -689,14 +702,16 @@ static int mongo_set_permission_ip(const char *kind, uint8_t *realm, const char
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
bson_t query, doc, child;
|
||||
bson_init(&query);
|
||||
@ -732,14 +747,16 @@ static int mongo_set_permission_ip(const char *kind, uint8_t *realm, const char
|
||||
static int mongo_add_origin(uint8_t *origin, uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
bson_t query, doc, child;
|
||||
bson_init(&query);
|
||||
@ -763,8 +780,9 @@ static int mongo_add_origin(uint8_t *origin, uint8_t *realm) {
|
||||
static int mongo_del_origin(uint8_t *origin) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
|
||||
@ -789,12 +807,14 @@ static int mongo_del_origin(uint8_t *origin) {
|
||||
static int mongo_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_list_t *realms) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
bson_t query, child;
|
||||
bson_init(&query);
|
||||
@ -867,8 +887,9 @@ static int mongo_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query, doc, child;
|
||||
bson_init(&query);
|
||||
@ -877,6 +898,9 @@ static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const
|
||||
|
||||
size_t klen = 9 + strlen(opt);
|
||||
char *_k = (char *)malloc(klen);
|
||||
if (!_k) {
|
||||
return -1;
|
||||
}
|
||||
strcpy(_k, "options.");
|
||||
strcat(_k, opt);
|
||||
|
||||
@ -907,8 +931,9 @@ static int mongo_set_realm_option_one(uint8_t *realm, unsigned long value, const
|
||||
static int mongo_list_realm_options(uint8_t *realm) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query, child;
|
||||
bson_init(&query);
|
||||
@ -991,8 +1016,9 @@ static int mongo_read_realms_ip_lists(const char *kind, ip_range_list_t *list) {
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -1057,8 +1083,9 @@ static void mongo_reread_realms(secrets_list_t *realms_list) {
|
||||
|
||||
mongoc_collection_t *collection = mongo_get_collection("realm");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -1139,13 +1166,13 @@ static void mongo_reread_realms(secrets_list_t *realms_list) {
|
||||
_v = (uint64_t)bson_iter_int64(&options_iter);
|
||||
}
|
||||
if (_v) {
|
||||
if (!strcmp(_k, "max-bps"))
|
||||
if (!strcmp(_k, "max-bps")) {
|
||||
rp->options.perf_options.max_bps = (band_limit_t)_v;
|
||||
else if (!strcmp(_k, "total-quota"))
|
||||
} else if (!strcmp(_k, "total-quota")) {
|
||||
rp->options.perf_options.total_quota = (vint)_v;
|
||||
else if (!strcmp(_k, "user-quota"))
|
||||
} else if (!strcmp(_k, "user-quota")) {
|
||||
rp->options.perf_options.user_quota = (vint)_v;
|
||||
else {
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", _k);
|
||||
}
|
||||
}
|
||||
@ -1168,8 +1195,9 @@ static void mongo_reread_realms(secrets_list_t *realms_list) {
|
||||
static int mongo_get_admin_user(const uint8_t *usname, uint8_t *realm, password_t pwd) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("admin_user");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
realm[0] = 0;
|
||||
pwd[0] = 0;
|
||||
@ -1215,8 +1243,9 @@ static int mongo_get_admin_user(const uint8_t *usname, uint8_t *realm, password_
|
||||
static int mongo_set_admin_user(const uint8_t *usname, const uint8_t *realm, const password_t pwd) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("admin_user");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -1244,8 +1273,9 @@ static int mongo_set_admin_user(const uint8_t *usname, const uint8_t *realm, con
|
||||
static int mongo_del_admin_user(const uint8_t *usname) {
|
||||
mongoc_collection_t *collection = mongo_get_collection("admin_user");
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query;
|
||||
bson_init(&query);
|
||||
@ -1267,8 +1297,9 @@ static int mongo_list_admin_users(int no_print) {
|
||||
const char *collection_name = "admin_user";
|
||||
mongoc_collection_t *collection = mongo_get_collection(collection_name);
|
||||
|
||||
if (!collection)
|
||||
if (!collection) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
bson_t query, child;
|
||||
bson_init(&query);
|
||||
|
||||
@ -60,24 +60,33 @@ typedef struct _Myconninfo Myconninfo;
|
||||
|
||||
static void MyconninfoFree(Myconninfo *co) {
|
||||
if (co) {
|
||||
if (co->host)
|
||||
if (co->host) {
|
||||
free(co->host);
|
||||
if (co->dbname)
|
||||
}
|
||||
if (co->dbname) {
|
||||
free(co->dbname);
|
||||
if (co->user)
|
||||
}
|
||||
if (co->user) {
|
||||
free(co->user);
|
||||
if (co->password)
|
||||
}
|
||||
if (co->password) {
|
||||
free(co->password);
|
||||
if (co->key)
|
||||
}
|
||||
if (co->key) {
|
||||
free(co->key);
|
||||
if (co->ca)
|
||||
}
|
||||
if (co->ca) {
|
||||
free(co->ca);
|
||||
if (co->cert)
|
||||
}
|
||||
if (co->cert) {
|
||||
free(co->cert);
|
||||
if (co->capath)
|
||||
}
|
||||
if (co->capath) {
|
||||
free(co->capath);
|
||||
if (co->cipher)
|
||||
}
|
||||
if (co->cipher) {
|
||||
free(co->cipher);
|
||||
}
|
||||
memset(co, 0, sizeof(Myconninfo));
|
||||
free(co);
|
||||
}
|
||||
@ -88,7 +97,7 @@ char *decryptPassword(char *in, const unsigned char *mykey) {
|
||||
char *out;
|
||||
unsigned char iv[8] = {0}; // changed
|
||||
AES_KEY key;
|
||||
unsigned char outdata[256]; // changed
|
||||
unsigned char outdata[256] = {0}; // changed
|
||||
AES_set_encrypt_key(mykey, 128, &key);
|
||||
int newTotalSize = decodedTextSize(in);
|
||||
int bytes_to_decode = strlen(in);
|
||||
@ -96,32 +105,27 @@ char *decryptPassword(char *in, const unsigned char *mykey) {
|
||||
char last[1024] = "";
|
||||
struct ctr_state state;
|
||||
init_ctr(&state, iv);
|
||||
memset(outdata, '\0', sizeof(outdata));
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
CRYPTO_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num,
|
||||
(block128_f)AES_encrypt);
|
||||
#else
|
||||
AES_ctr128_encrypt(encryptedText, outdata, newTotalSize, &key, state.ivec, state.ecount, &state.num);
|
||||
#endif
|
||||
|
||||
strcat(last, (char *)outdata);
|
||||
out = (char *)malloc(sizeof(char) * strlen(last));
|
||||
out = (char *)malloc(sizeof(char) * (strlen(last) + 1)); // add 1 to allocate space for terminating '\0'
|
||||
strcpy(out, last);
|
||||
return out;
|
||||
}
|
||||
|
||||
static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
|
||||
Myconninfo *co = (Myconninfo *)malloc(sizeof(Myconninfo));
|
||||
memset(co, 0, sizeof(Myconninfo));
|
||||
Myconninfo *co = (Myconninfo *)calloc(1, sizeof(Myconninfo));
|
||||
if (userdb) {
|
||||
char *s0 = strdup(userdb);
|
||||
char *s = s0;
|
||||
|
||||
while (s && *s) {
|
||||
|
||||
while (*s && (*s == ' '))
|
||||
while (*s && (*s == ' ')) {
|
||||
++s;
|
||||
}
|
||||
char *snext = strstr(s, " ");
|
||||
if (snext) {
|
||||
*snext = 0;
|
||||
@ -139,69 +143,69 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
|
||||
}
|
||||
|
||||
*seq = 0;
|
||||
if (!strcmp(s, "host"))
|
||||
if (!strcmp(s, "host")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ip"))
|
||||
} else if (!strcmp(s, "ip")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "addr"))
|
||||
} else if (!strcmp(s, "addr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ipaddr"))
|
||||
} else if (!strcmp(s, "ipaddr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "hostaddr"))
|
||||
} else if (!strcmp(s, "hostaddr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "dbname"))
|
||||
} else if (!strcmp(s, "dbname")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "db"))
|
||||
} else if (!strcmp(s, "db")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "database"))
|
||||
} else if (!strcmp(s, "database")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "user"))
|
||||
} else if (!strcmp(s, "user")) {
|
||||
co->user = strdup(seq + 1);
|
||||
else if (!strcmp(s, "uname"))
|
||||
} else if (!strcmp(s, "uname")) {
|
||||
co->user = strdup(seq + 1);
|
||||
else if (!strcmp(s, "name"))
|
||||
} else if (!strcmp(s, "name")) {
|
||||
co->user = strdup(seq + 1);
|
||||
else if (!strcmp(s, "username"))
|
||||
} else if (!strcmp(s, "username")) {
|
||||
co->user = strdup(seq + 1);
|
||||
else if (!strcmp(s, "password"))
|
||||
} else if (!strcmp(s, "password")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "pwd"))
|
||||
} else if (!strcmp(s, "pwd")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "passwd"))
|
||||
} else if (!strcmp(s, "passwd")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "secret"))
|
||||
} else if (!strcmp(s, "secret")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "port"))
|
||||
} else if (!strcmp(s, "port")) {
|
||||
co->port = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "p"))
|
||||
} else if (!strcmp(s, "p")) {
|
||||
co->port = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "connect_timeout"))
|
||||
} else if (!strcmp(s, "connect_timeout")) {
|
||||
co->connect_timeout = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "timeout"))
|
||||
} else if (!strcmp(s, "timeout")) {
|
||||
co->connect_timeout = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "read_timeout"))
|
||||
} else if (!strcmp(s, "read_timeout")) {
|
||||
co->read_timeout = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "key"))
|
||||
} else if (!strcmp(s, "key")) {
|
||||
co->key = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ssl-key"))
|
||||
} else if (!strcmp(s, "ssl-key")) {
|
||||
co->key = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ca"))
|
||||
} else if (!strcmp(s, "ca")) {
|
||||
co->ca = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ssl-ca"))
|
||||
} else if (!strcmp(s, "ssl-ca")) {
|
||||
co->ca = strdup(seq + 1);
|
||||
else if (!strcmp(s, "capath"))
|
||||
} else if (!strcmp(s, "capath")) {
|
||||
co->capath = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ssl-capath"))
|
||||
} else if (!strcmp(s, "ssl-capath")) {
|
||||
co->capath = strdup(seq + 1);
|
||||
else if (!strcmp(s, "cert"))
|
||||
} else if (!strcmp(s, "cert")) {
|
||||
co->cert = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ssl-cert"))
|
||||
} else if (!strcmp(s, "ssl-cert")) {
|
||||
co->cert = strdup(seq + 1);
|
||||
else if (!strcmp(s, "cipher"))
|
||||
} else if (!strcmp(s, "cipher")) {
|
||||
co->cipher = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ssl-cipher"))
|
||||
} else if (!strcmp(s, "ssl-cipher")) {
|
||||
co->cipher = strdup(seq + 1);
|
||||
else {
|
||||
} else {
|
||||
MyconninfoFree(co);
|
||||
co = NULL;
|
||||
if (errmsg) {
|
||||
@ -217,14 +221,18 @@ static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
|
||||
}
|
||||
|
||||
if (co) {
|
||||
if (!(co->dbname))
|
||||
if (!(co->dbname)) {
|
||||
co->dbname = strdup("0");
|
||||
if (!(co->host))
|
||||
}
|
||||
if (!(co->host)) {
|
||||
co->host = strdup("127.0.0.1");
|
||||
if (!(co->user))
|
||||
}
|
||||
if (!(co->user)) {
|
||||
co->user = strdup("");
|
||||
if (!(co->password))
|
||||
}
|
||||
if (!(co->password)) {
|
||||
co->password = strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
return co;
|
||||
@ -270,10 +278,12 @@ static MYSQL *get_mydb_connection(void) {
|
||||
if (!mydbconnection) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MySQL DB connection\n");
|
||||
} else {
|
||||
if (co->connect_timeout)
|
||||
if (co->connect_timeout) {
|
||||
mysql_options(mydbconnection, MYSQL_OPT_CONNECT_TIMEOUT, &(co->connect_timeout));
|
||||
if (co->read_timeout)
|
||||
}
|
||||
if (co->read_timeout) {
|
||||
mysql_options(mydbconnection, MYSQL_OPT_READ_TIMEOUT, &(co->read_timeout));
|
||||
}
|
||||
if (co->ca || co->capath || co->cert || co->cipher || co->key) {
|
||||
mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher);
|
||||
}
|
||||
@ -298,8 +308,9 @@ static MYSQL *get_mydb_connection(void) {
|
||||
if (turn_params.secret_key_file[0]) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Encryption with AES is activated.\n");
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is secure.\n");
|
||||
} else
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Connection is not secure.\n");
|
||||
}
|
||||
donot_print_connection_success = 1;
|
||||
}
|
||||
}
|
||||
@ -348,8 +359,9 @@ static int mysql_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -385,18 +397,16 @@ static int mysql_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
char kval[sizeof(hmackey_t) + sizeof(hmackey_t) + 1];
|
||||
memcpy(kval, row[0], sz);
|
||||
kval[sz] = 0;
|
||||
if (convert_string_key_to_binary(kval, key, sz / 2) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
convert_string_key_to_binary(kval, key, sz / 2);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -451,8 +461,9 @@ static int mysql_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -531,8 +542,9 @@ static int mysql_list_oauth_keys(secrets_list_t *kids, secrets_list_t *teas, sec
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -630,8 +642,9 @@ static int mysql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
MYSQL *myc = get_mydb_connection();
|
||||
if (myc) {
|
||||
@ -675,8 +688,9 @@ static int mysql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -686,8 +700,9 @@ static int mysql_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
if (realm[0]) {
|
||||
@ -737,8 +752,9 @@ static int mysql_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -750,10 +766,11 @@ static int mysql_del_secret(uint8_t *secret, uint8_t *realm) {
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
MYSQL *myc = get_mydb_connection();
|
||||
if (myc) {
|
||||
if (!secret || (secret[0] == 0))
|
||||
if (!secret || (secret[0] == 0)) {
|
||||
snprintf(statement, sizeof(statement), "delete from turn_secret where realm='%s'", realm);
|
||||
else
|
||||
} else {
|
||||
snprintf(statement, sizeof(statement), "delete from turn_secret where value='%s' and realm='%s'", secret, realm);
|
||||
}
|
||||
mysql_query(myc, statement);
|
||||
ret = 0;
|
||||
}
|
||||
@ -781,8 +798,9 @@ static int mysql_set_permission_ip(const char *kind, uint8_t *realm, const char
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -844,8 +862,9 @@ static int mysql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -894,8 +913,9 @@ static int mysql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -959,8 +979,9 @@ static int mysql_list_realm_options(uint8_t *realm) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -1033,8 +1054,9 @@ static int mysql_get_ip_list(const char *kind, ip_range_list_t *list) {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -1077,8 +1099,9 @@ static void mysql_reread_realms(secrets_list_t *realms_list) {
|
||||
update_o_to_realm(o_to_realm_new);
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
{
|
||||
@ -1136,13 +1159,13 @@ static void mysql_reread_realms(secrets_list_t *realms_list) {
|
||||
memcpy(vval, row[2], sz);
|
||||
vval[sz] = 0;
|
||||
realm_params_t *rp = get_realm(rval);
|
||||
if (!strcmp(oval, "max-bps"))
|
||||
if (!strcmp(oval, "max-bps")) {
|
||||
rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval, NULL, 10);
|
||||
else if (!strcmp(oval, "total-quota"))
|
||||
} else if (!strcmp(oval, "total-quota")) {
|
||||
rp->options.perf_options.total_quota = (vint)atoi(vval);
|
||||
else if (!strcmp(oval, "user-quota"))
|
||||
} else if (!strcmp(oval, "user-quota")) {
|
||||
rp->options.perf_options.user_quota = (vint)atoi(vval);
|
||||
else {
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval);
|
||||
}
|
||||
}
|
||||
@ -1151,8 +1174,9 @@ static void mysql_reread_realms(secrets_list_t *realms_list) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1187,8 +1211,9 @@ static int mysql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
@ -1271,8 +1296,9 @@ static int mysql_list_admin_users(int no_print) {
|
||||
}
|
||||
}
|
||||
|
||||
if (mres)
|
||||
if (mres) {
|
||||
mysql_free_result(mres);
|
||||
}
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@ -68,8 +68,9 @@ static PGconn *get_pqdb_connection(void) {
|
||||
}
|
||||
} else {
|
||||
PQconninfoFree(co);
|
||||
if (errmsg)
|
||||
if (errmsg) {
|
||||
free(errmsg);
|
||||
}
|
||||
pqdbconnection = PQconnectdb(pud->userdb);
|
||||
if (!pqdbconnection) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open PostgreSQL DB connection: <%s>, runtime error\n",
|
||||
@ -144,9 +145,8 @@ static int pgsql_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
|
||||
if (((size_t)len < sz * 2) || (strlen(kval) < sz * 2)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s, user %s\n", kval, usname);
|
||||
} else if (convert_string_key_to_binary(kval, key, sz) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", kval, usname);
|
||||
} else {
|
||||
convert_string_key_to_binary(kval, key, sz);
|
||||
ret = 0;
|
||||
}
|
||||
} else {
|
||||
@ -154,8 +154,9 @@ static int pgsql_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
}
|
||||
}
|
||||
|
||||
if (res)
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
@ -363,8 +364,9 @@ static int pgsql_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if (pqc) {
|
||||
@ -412,8 +414,9 @@ static int pgsql_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
if (realm[0]) {
|
||||
@ -465,10 +468,11 @@ static int pgsql_del_secret(uint8_t *secret, uint8_t *realm) {
|
||||
char statement[TURN_LONG_STRING_SIZE];
|
||||
PGconn *pqc = get_pqdb_connection();
|
||||
if (pqc) {
|
||||
if (!secret || (secret[0] == 0))
|
||||
if (!secret || (secret[0] == 0)) {
|
||||
snprintf(statement, sizeof(statement), "delete from turn_secret where realm='%s'", realm);
|
||||
else
|
||||
} else {
|
||||
snprintf(statement, sizeof(statement), "delete from turn_secret where value='%s' and realm='%s'", secret, realm);
|
||||
}
|
||||
|
||||
PGresult *res = PQexec(pqc, statement);
|
||||
if (res) {
|
||||
@ -504,8 +508,9 @@ static int pgsql_set_permission_ip(const char *kind, uint8_t *realm, const char
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -580,8 +585,9 @@ static int pgsql_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -777,8 +783,7 @@ static void pgsql_reread_realms(secrets_list_t *realms_list) {
|
||||
if (rval) {
|
||||
get_realm(rval);
|
||||
ur_string_map_value_type value = strdup(rval);
|
||||
int ret = ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)oval, value);
|
||||
if (ret == -1) {
|
||||
if (!ur_string_map_put(o_to_realm_new, (ur_string_map_key_type)oval, value)) {
|
||||
free(value);
|
||||
}
|
||||
}
|
||||
@ -834,13 +839,13 @@ static void pgsql_reread_realms(secrets_list_t *realms_list) {
|
||||
char *vval = PQgetvalue(res, i, 2);
|
||||
if (rval && oval && vval) {
|
||||
realm_params_t *rp = get_realm(rval);
|
||||
if (!strcmp(oval, "max-bps"))
|
||||
if (!strcmp(oval, "max-bps")) {
|
||||
rp->options.perf_options.max_bps = (band_limit_t)strtoul(vval, NULL, 10);
|
||||
else if (!strcmp(oval, "total-quota"))
|
||||
} else if (!strcmp(oval, "total-quota")) {
|
||||
rp->options.perf_options.total_quota = (vint)atoi(vval);
|
||||
else if (!strcmp(oval, "user-quota"))
|
||||
} else if (!strcmp(oval, "user-quota")) {
|
||||
rp->options.perf_options.user_quota = (vint)atoi(vval);
|
||||
else {
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval);
|
||||
}
|
||||
}
|
||||
@ -882,8 +887,9 @@ static int pgsql_get_admin_user(const uint8_t *usname, uint8_t *realm, password_
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
if (res)
|
||||
if (res) {
|
||||
PQclear(res);
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -33,7 +33,7 @@
|
||||
#include "../mainrelay.h"
|
||||
|
||||
#if !defined(TURN_NO_HIREDIS)
|
||||
#include "hiredis_libevent2.h"
|
||||
#include "../hiredis_libevent2.h"
|
||||
#include <hiredis/hiredis.h>
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -49,6 +49,7 @@ static void turnFreeRedisReply(void *reply) {
|
||||
struct _Ryconninfo {
|
||||
char *host;
|
||||
char *dbname;
|
||||
char *user;
|
||||
char *password;
|
||||
unsigned int connect_timeout;
|
||||
unsigned int port;
|
||||
@ -58,28 +59,34 @@ typedef struct _Ryconninfo Ryconninfo;
|
||||
|
||||
static void RyconninfoFree(Ryconninfo *co) {
|
||||
if (co) {
|
||||
if (co->host)
|
||||
if (co->host) {
|
||||
free(co->host);
|
||||
if (co->dbname)
|
||||
}
|
||||
if (co->dbname) {
|
||||
free(co->dbname);
|
||||
if (co->password)
|
||||
}
|
||||
if (co->user) {
|
||||
free(co->user);
|
||||
}
|
||||
if (co->password) {
|
||||
free(co->password);
|
||||
}
|
||||
memset(co, 0, sizeof(Ryconninfo));
|
||||
free(co);
|
||||
}
|
||||
}
|
||||
|
||||
static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
|
||||
Ryconninfo *co = (Ryconninfo *)malloc(sizeof(Ryconninfo));
|
||||
memset(co, 0, sizeof(Ryconninfo));
|
||||
Ryconninfo *co = (Ryconninfo *)calloc(1, sizeof(Ryconninfo));
|
||||
if (userdb) {
|
||||
char *s0 = strdup(userdb);
|
||||
char *s = s0;
|
||||
|
||||
while (s && *s) {
|
||||
|
||||
while (*s && (*s == ' '))
|
||||
while (*s && (*s == ' ')) {
|
||||
++s;
|
||||
}
|
||||
char *snext = strstr(s, " ");
|
||||
if (snext) {
|
||||
*snext = 0;
|
||||
@ -97,47 +104,47 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
|
||||
}
|
||||
|
||||
*seq = 0;
|
||||
if (!strcmp(s, "host"))
|
||||
if (!strcmp(s, "host")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ip"))
|
||||
} else if (!strcmp(s, "ip")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "addr"))
|
||||
} else if (!strcmp(s, "addr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "ipaddr"))
|
||||
} else if (!strcmp(s, "ipaddr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "hostaddr"))
|
||||
} else if (!strcmp(s, "hostaddr")) {
|
||||
co->host = strdup(seq + 1);
|
||||
else if (!strcmp(s, "dbname"))
|
||||
} else if (!strcmp(s, "dbname")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "db"))
|
||||
} else if (!strcmp(s, "db")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "database"))
|
||||
} else if (!strcmp(s, "database")) {
|
||||
co->dbname = strdup(seq + 1);
|
||||
else if (!strcmp(s, "user"))
|
||||
;
|
||||
else if (!strcmp(s, "uname"))
|
||||
;
|
||||
else if (!strcmp(s, "name"))
|
||||
;
|
||||
else if (!strcmp(s, "username"))
|
||||
;
|
||||
else if (!strcmp(s, "password"))
|
||||
} else if (!strcmp(s, "user")) {
|
||||
co->user = strdup(seq + 1);
|
||||
} else if (!strcmp(s, "uname")) {
|
||||
co->user = strdup(seq + 1);
|
||||
} else if (!strcmp(s, "name")) {
|
||||
co->user = strdup(seq + 1);
|
||||
} else if (!strcmp(s, "username")) {
|
||||
co->user = strdup(seq + 1);
|
||||
} else if (!strcmp(s, "password")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "pwd"))
|
||||
} else if (!strcmp(s, "pwd")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "passwd"))
|
||||
} else if (!strcmp(s, "passwd")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "secret"))
|
||||
} else if (!strcmp(s, "secret")) {
|
||||
co->password = strdup(seq + 1);
|
||||
else if (!strcmp(s, "port"))
|
||||
} else if (!strcmp(s, "port")) {
|
||||
co->port = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "p"))
|
||||
} else if (!strcmp(s, "p")) {
|
||||
co->port = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "connect_timeout"))
|
||||
} else if (!strcmp(s, "connect_timeout")) {
|
||||
co->connect_timeout = (unsigned int)atoi(seq + 1);
|
||||
else if (!strcmp(s, "timeout"))
|
||||
} else if (!strcmp(s, "timeout")) {
|
||||
co->connect_timeout = (unsigned int)atoi(seq + 1);
|
||||
else {
|
||||
} else {
|
||||
RyconninfoFree(co);
|
||||
co = NULL;
|
||||
if (errmsg) {
|
||||
@ -153,12 +160,12 @@ static Ryconninfo *RyconninfoParse(const char *userdb, char **errmsg) {
|
||||
}
|
||||
|
||||
if (co) {
|
||||
if (!(co->dbname))
|
||||
if (!(co->dbname)) {
|
||||
co->dbname = strdup("0");
|
||||
if (!(co->host))
|
||||
}
|
||||
if (!(co->host)) {
|
||||
co->host = strdup("127.0.0.1");
|
||||
if (!(co->password))
|
||||
co->password = strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
return co;
|
||||
@ -195,13 +202,16 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
|
||||
|
||||
char ip[256] = "\0";
|
||||
int port = DEFAULT_REDIS_PORT;
|
||||
if (co->host)
|
||||
if (co->host) {
|
||||
STRCPY(ip, co->host);
|
||||
if (!ip[0])
|
||||
}
|
||||
if (!ip[0]) {
|
||||
strncpy(ip, "127.0.0.1", sizeof(ip));
|
||||
}
|
||||
|
||||
if (co->port)
|
||||
if (co->port) {
|
||||
port = (int)(co->port);
|
||||
}
|
||||
|
||||
if (co->connect_timeout) {
|
||||
struct timeval tv;
|
||||
@ -215,8 +225,12 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
|
||||
if (!rc) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB async connection\n");
|
||||
} else {
|
||||
if (co->password) {
|
||||
turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password));
|
||||
if (co->password && strlen(co->password)) {
|
||||
if (co->user && strlen(co->user)) {
|
||||
turnFreeRedisReply(redisCommand(rc, "AUTH %s %s", co->user, co->password));
|
||||
} else {
|
||||
turnFreeRedisReply(redisCommand(rc, "AUTH %s", co->password));
|
||||
}
|
||||
}
|
||||
if (co->dbname) {
|
||||
turnFreeRedisReply(redisCommand(rc, "select %s", co->dbname));
|
||||
@ -233,8 +247,9 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -257,7 +272,7 @@ redis_context_handle get_redis_async_connection(struct event_base *base, redis_s
|
||||
}
|
||||
}
|
||||
|
||||
ret = redisLibeventAttach(base, co->host, co->port, co->password, atoi(co->dbname));
|
||||
ret = redisLibeventAttach(base, co->host, co->port, co->user, co->password, atoi(co->dbname));
|
||||
|
||||
if (!ret) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize Redis DB connection\n");
|
||||
@ -310,13 +325,16 @@ static redisContext *get_redis_connection(void) {
|
||||
} else {
|
||||
char ip[256] = "\0";
|
||||
int port = DEFAULT_REDIS_PORT;
|
||||
if (co->host)
|
||||
if (co->host) {
|
||||
STRCPY(ip, co->host);
|
||||
if (!ip[0])
|
||||
}
|
||||
if (!ip[0]) {
|
||||
strncpy(ip, "127.0.0.1", sizeof(ip));
|
||||
}
|
||||
|
||||
if (co->port)
|
||||
if (co->port) {
|
||||
port = (int)(co->port);
|
||||
}
|
||||
|
||||
if (co->connect_timeout) {
|
||||
struct timeval tv;
|
||||
@ -334,8 +352,13 @@ static redisContext *get_redis_connection(void) {
|
||||
}
|
||||
redisFree(redisconnection);
|
||||
redisconnection = NULL;
|
||||
} else if (co->password) {
|
||||
void *reply = redisCommand(redisconnection, "AUTH %s", co->password);
|
||||
} else if (co->password && strlen(co->password)) {
|
||||
void *reply;
|
||||
if (co->user && strlen(co->user)) {
|
||||
reply = redisCommand(redisconnection, "AUTH %s %s", co->user, co->password);
|
||||
} else {
|
||||
reply = redisCommand(redisconnection, "AUTH %s", co->password);
|
||||
}
|
||||
if (!reply) {
|
||||
if (redisconnection->err && redisconnection->errstr[0]) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Redis: %s\n", redisconnection->errstr);
|
||||
@ -391,11 +414,12 @@ static int set_redis_realm_opt(char *realm, const char *key, unsigned long *valu
|
||||
|
||||
rget = (redisReply *)redisCommand(rc, s);
|
||||
if (rget) {
|
||||
if (rget->type == REDIS_REPLY_ERROR)
|
||||
if (rget->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str);
|
||||
else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL)
|
||||
} else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
|
||||
}
|
||||
} else {
|
||||
lock_realms();
|
||||
*value = (unsigned long)atol(rget->str);
|
||||
@ -418,11 +442,12 @@ static int redis_get_auth_secrets(secrets_list_t *sl, uint8_t *realm) {
|
||||
redisReply *reply = (redisReply *)redisCommand(rc, "smembers turn/realm/%s/secret", (char *)realm);
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -446,18 +471,18 @@ static int redis_get_user_key(uint8_t *usname, uint8_t *realm, hmackey_t key) {
|
||||
snprintf(s, sizeof(s), "get turn/realm/%s/user/%s/key", (char *)realm, usname);
|
||||
redisReply *rget = (redisReply *)redisCommand(rc, s);
|
||||
if (rget) {
|
||||
if (rget->type == REDIS_REPLY_ERROR)
|
||||
if (rget->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str);
|
||||
else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL)
|
||||
} else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
|
||||
}
|
||||
} else {
|
||||
size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
|
||||
if (strlen(rget->str) < sz * 2) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s, user %s\n", rget->str, usname);
|
||||
} else if (convert_string_key_to_binary(rget->str, key, sz) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n", rget->str, usname);
|
||||
} else {
|
||||
convert_string_key_to_binary(rget->str, key, sz);
|
||||
ret = 0;
|
||||
}
|
||||
}
|
||||
@ -477,11 +502,12 @@ static int redis_get_oauth_key(const uint8_t *kid, oauth_key_data_raw *key) {
|
||||
snprintf(s, sizeof(s), "hgetall turn/oauth/kid/%s", (const char *)kid);
|
||||
redisReply *reply = (redisReply *)redisCommand(rc, s);
|
||||
if (reply) {
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else if (reply->elements > 1) {
|
||||
size_t i;
|
||||
for (i = 0; i < (reply->elements) / 2; ++i) {
|
||||
@ -572,8 +598,9 @@ static int redis_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
redisContext *rc = get_redis_connection();
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
if (rc) {
|
||||
secrets_list_t keys;
|
||||
@ -592,11 +619,12 @@ static int redis_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -614,23 +642,27 @@ static int redis_list_users(uint8_t *realm, secrets_list_t *users, secrets_list_
|
||||
char *s = keys.secrets[isz];
|
||||
|
||||
char *sh = strstr(s, "turn/realm/");
|
||||
if (sh != s)
|
||||
if (sh != s) {
|
||||
continue;
|
||||
}
|
||||
sh += rhsz;
|
||||
char *st = strchr(sh, '/');
|
||||
if (!st)
|
||||
if (!st) {
|
||||
continue;
|
||||
}
|
||||
*st = 0;
|
||||
char *sr = sh;
|
||||
++st;
|
||||
|
||||
sh = strstr(st, "user/");
|
||||
if (sh != st)
|
||||
if (sh != st) {
|
||||
continue;
|
||||
}
|
||||
sh += uhsz;
|
||||
st = strchr(sh, '/');
|
||||
if (!st)
|
||||
if (!st) {
|
||||
continue;
|
||||
}
|
||||
*st = 0;
|
||||
char *su = sh;
|
||||
|
||||
@ -718,8 +750,9 @@ static int redis_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
redisContext *rc = get_redis_connection();
|
||||
@ -737,11 +770,12 @@ static int redis_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
|
||||
init_secrets_list(&keys);
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -760,19 +794,22 @@ static int redis_list_secrets(uint8_t *realm, secrets_list_t *secrets, secrets_l
|
||||
} else if (rget->type == REDIS_REPLY_STRING) {
|
||||
printf("%s\n", rget->str);
|
||||
} else if (rget->type != REDIS_REPLY_ARRAY) {
|
||||
if (rget->type != REDIS_REPLY_NIL)
|
||||
if (rget->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
|
||||
}
|
||||
} else {
|
||||
|
||||
char *s = keys.secrets[isz];
|
||||
|
||||
char *sh = strstr(s, "turn/realm/");
|
||||
if (sh != s)
|
||||
if (sh != s) {
|
||||
continue;
|
||||
}
|
||||
sh += rhsz;
|
||||
char *st = strchr(sh, '/');
|
||||
if (!st)
|
||||
if (!st) {
|
||||
continue;
|
||||
}
|
||||
*st = 0;
|
||||
const char *rval = sh;
|
||||
|
||||
@ -840,8 +877,9 @@ static int redis_set_permission_ip(const char *kind, uint8_t *realm, const char
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -896,8 +934,9 @@ static int redis_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
int ret = -1;
|
||||
|
||||
uint8_t realm0[STUN_MAX_REALM_SIZE + 1] = "\0";
|
||||
if (!realm)
|
||||
if (!realm) {
|
||||
realm = realm0;
|
||||
}
|
||||
|
||||
donot_print_connection_success = 1;
|
||||
|
||||
@ -914,11 +953,12 @@ static int redis_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
reply = (redisReply *)redisCommand(rc, "keys turn/origin/*");
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
size_t offset = strlen("turn/origin/");
|
||||
@ -937,11 +977,12 @@ static int redis_list_origins(uint8_t *realm, secrets_list_t *origins, secrets_l
|
||||
reply = (redisReply *)redisCommand(rc, "get turn/origin/%s", o);
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_STRING) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_STRING) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
if (!(realm && realm[0] && strcmp((char *)realm, reply->str))) {
|
||||
if (origins) {
|
||||
@ -970,10 +1011,11 @@ static int redis_set_realm_option_one(uint8_t *realm, unsigned long value, const
|
||||
if (rc) {
|
||||
char s[TURN_LONG_STRING_SIZE];
|
||||
|
||||
if (value > 0)
|
||||
if (value > 0) {
|
||||
snprintf(s, sizeof(s), "set turn/realm/%s/%s %lu", (char *)realm, opt, (unsigned long)value);
|
||||
else
|
||||
} else {
|
||||
snprintf(s, sizeof(s), "del turn/realm/%s/%s", (char *)realm, opt);
|
||||
}
|
||||
|
||||
turnFreeRedisReply(redisCommand(rc, s));
|
||||
turnFreeRedisReply(redisCommand(rc, "save"));
|
||||
@ -1002,11 +1044,12 @@ static int redis_list_realm_options(uint8_t *realm) {
|
||||
}
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -1028,11 +1071,12 @@ static int redis_list_realm_options(uint8_t *realm) {
|
||||
reply = (redisReply *)redisCommand(rc, "get %s", o);
|
||||
if (reply) {
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_STRING) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_STRING) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
printf("%s = %s\n", o + offset, reply->str);
|
||||
}
|
||||
@ -1070,11 +1114,12 @@ static int redis_get_ip_list(const char *kind, ip_range_list_t *list) {
|
||||
|
||||
init_secrets_list(&keys);
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -1103,8 +1148,9 @@ static int redis_get_ip_list(const char *kind, ip_range_list_t *list) {
|
||||
} else if (rget->type == REDIS_REPLY_STRING) {
|
||||
add_ip_list_range(rget->str, realm, list);
|
||||
} else if (rget->type != REDIS_REPLY_ARRAY) {
|
||||
if (rget->type != REDIS_REPLY_NIL)
|
||||
if (rget->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < rget->elements; ++i) {
|
||||
@ -1145,11 +1191,12 @@ static void redis_reread_realms(secrets_list_t *realms_list) {
|
||||
|
||||
char s[1025];
|
||||
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < reply->elements; ++i) {
|
||||
@ -1164,11 +1211,12 @@ static void redis_reread_realms(secrets_list_t *realms_list) {
|
||||
snprintf(s, sizeof(s), "get %s", keys.secrets[isz]);
|
||||
redisReply *rget = (redisReply *)redisCommand(rc, s);
|
||||
if (rget) {
|
||||
if (rget->type == REDIS_REPLY_ERROR)
|
||||
if (rget->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", rget->str);
|
||||
else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL)
|
||||
} else if (rget->type != REDIS_REPLY_STRING) {
|
||||
if (rget->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", rget->type);
|
||||
}
|
||||
} else {
|
||||
get_realm(rget->str);
|
||||
ur_string_map_value_type value = strdup(rget->str);
|
||||
@ -1243,11 +1291,12 @@ static int redis_get_admin_user(const uint8_t *usname, uint8_t *realm, password_
|
||||
snprintf(s, sizeof(s), "hgetall turn/admin_user/%s", (const char *)usname);
|
||||
redisReply *reply = (redisReply *)redisCommand(rc, s);
|
||||
if (reply) {
|
||||
if (reply->type == REDIS_REPLY_ERROR)
|
||||
if (reply->type == REDIS_REPLY_ERROR) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error: %s\n", reply->str);
|
||||
else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL)
|
||||
} else if (reply->type != REDIS_REPLY_ARRAY) {
|
||||
if (reply->type != REDIS_REPLY_NIL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unexpected type: %d\n", reply->type);
|
||||
}
|
||||
} else if (reply->elements > 1) {
|
||||
size_t i;
|
||||
for (i = 0; i < (reply->elements) / 2; ++i) {
|
||||
|
||||
@ -32,8 +32,8 @@
|
||||
#ifndef __DBD_REDIS__
|
||||
#define __DBD_REDIS__
|
||||
|
||||
#include "../hiredis_libevent2.h"
|
||||
#include "dbdriver.h"
|
||||
#include "hiredis_libevent2.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,7 @@ static void make_connection_key(void) { (void)pthread_key_create(&connection_key
|
||||
pthread_key_t connection_key;
|
||||
pthread_once_t connection_key_once = PTHREAD_ONCE_INIT;
|
||||
|
||||
int convert_string_key_to_binary(char *keysource, hmackey_t key, size_t sz) {
|
||||
void convert_string_key_to_binary(char const *keysource, hmackey_t key, size_t sz) {
|
||||
char is[3];
|
||||
size_t i;
|
||||
unsigned int v;
|
||||
@ -56,14 +56,14 @@ int convert_string_key_to_binary(char *keysource, hmackey_t key, size_t sz) {
|
||||
sscanf(is, "%02x", &v);
|
||||
key[i] = (unsigned char)v;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
persistent_users_db_t *get_persistent_users_db(void) { return &(turn_params.default_users_db.persistent_users_db); }
|
||||
|
||||
const turn_dbdriver_t *get_dbdriver(void) {
|
||||
if (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_UNKNOWN)
|
||||
if (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_UNKNOWN) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(void)pthread_once(&connection_key_once, make_connection_key);
|
||||
|
||||
|
||||
@ -79,7 +79,7 @@ typedef struct _turn_dbdriver_t {
|
||||
|
||||
/////////// USER DB CHECK //////////////////
|
||||
|
||||
int convert_string_key_to_binary(char *keysource, hmackey_t key, size_t sz);
|
||||
void convert_string_key_to_binary(char const *keysource, hmackey_t key, size_t sz);
|
||||
persistent_users_db_t *get_persistent_users_db(void);
|
||||
const turn_dbdriver_t *get_dbdriver(void);
|
||||
char *sanitize_userdb_string(char *udb);
|
||||
|
||||
@ -120,8 +120,9 @@ int is_dtls_message(const unsigned char *buf, int len) {
|
||||
|
||||
/* 0 - 1.0, 1 - 1.2 */
|
||||
int get_dtls_version(const unsigned char *buf, int len) {
|
||||
if (buf && (len > 3) && (buf[2] == 0xfd))
|
||||
if (buf && (len > 3) && (buf[2] == 0xfd)) {
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -134,8 +135,9 @@ static void calculate_cookie(SSL *ssl, unsigned char *cookie_secret, unsigned in
|
||||
long inum = (cookie_length - (((long)cookie_secret) % sizeof(long))) / sizeof(long);
|
||||
long i = 0;
|
||||
long *ip = (long *)cookie_secret;
|
||||
for (i = 0; i < inum; ++i, ++ip)
|
||||
for (i = 0; i < inum; ++i, ++ip) {
|
||||
*ip = rv;
|
||||
}
|
||||
}
|
||||
|
||||
static int generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie_len) {
|
||||
@ -199,12 +201,7 @@ static int generate_cookie(SSL *ssl, unsigned char *cookie, unsigned int *cookie
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int verify_cookie(SSL *ssl,
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
const
|
||||
#endif
|
||||
unsigned char *cookie,
|
||||
unsigned int cookie_len) {
|
||||
static int verify_cookie(SSL *ssl, const unsigned char *cookie, unsigned int cookie_len) {
|
||||
unsigned int resultlength = 0;
|
||||
unsigned char result[COOKIE_SECRET_LENGTH];
|
||||
|
||||
@ -226,13 +223,15 @@ static ioa_socket_handle dtls_accept_client_connection(dtls_listener_relay_serve
|
||||
ioa_network_buffer_handle nbh) {
|
||||
FUNCSTART;
|
||||
|
||||
if (!ssl)
|
||||
if (!server || !ssl) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int rc = ssl_read(sock->fd, ssl, nbh, server->verbose);
|
||||
|
||||
if (rc < 0)
|
||||
if (rc < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
addr_debug_print(server->verbose, remote_addr, "Accepted connection from");
|
||||
|
||||
@ -280,14 +279,8 @@ static ioa_socket_handle dtls_server_input_handler(dtls_listener_relay_server_ty
|
||||
|
||||
SSL_set_bio(connecting_ssl, NULL, wbio);
|
||||
SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
|
||||
| SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
|
||||
#endif
|
||||
#else
|
||||
#if defined(SSL_OP_NO_RENEGOTIATION)
|
||||
| SSL_OP_NO_RENEGOTIATION
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
SSL_set_max_cert_list(connecting_ssl, 655350);
|
||||
@ -387,10 +380,10 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, struct mes
|
||||
thrid = (long)pthread_self();
|
||||
#endif
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
|
||||
"%s: 111.111: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, "
|
||||
"s=0x%lx, done=%d, tbc=%d\n",
|
||||
__FUNCTION__, thrid, (long)amap, (long)(chs->sockets_container), (char *)saddr, (char *)rsaddr,
|
||||
(long)s, (int)(chs->done), (int)(chs->tobeclosed));
|
||||
"%s: 111.111: thrid=0x%lx: Amap = %p, socket container=%p, local addr %s, remote addr %s, "
|
||||
"s=%p, done=%d, tbc=%d\n",
|
||||
__FUNCTION__, thrid, amap, chs->sockets_container, (char *)saddr, (char *)rsaddr, s,
|
||||
(int)(chs->done), (int)(chs->tobeclosed));
|
||||
}
|
||||
}
|
||||
|
||||
@ -413,10 +406,10 @@ static int handle_udp_packet(dtls_listener_relay_server_type *server, struct mes
|
||||
thrid = (long)pthread_self();
|
||||
#endif
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO,
|
||||
"%s: 111.222: thrid=0x%lx: Amap = 0x%lx, socket container=0x%lx, local addr %s, remote addr %s, "
|
||||
"%s: 111.222: thrid=0x%lx: Amap = %p, socket container=%p, local addr %s, remote addr %s, "
|
||||
"s=0x%lx, done=%d, tbc=%d, st=%d, sat=%d\n",
|
||||
__FUNCTION__, thrid, (long)amap, (long)(chs->sockets_container), (char *)saddr, (char *)rsaddr,
|
||||
(long)chs, (int)(chs->done), (int)(chs->tobeclosed), (int)(chs->st), (int)(chs->sat));
|
||||
__FUNCTION__, thrid, amap, chs->sockets_container, (char *)saddr, (char *)rsaddr, (long)chs,
|
||||
(int)(chs->done), (int)(chs->tobeclosed), (int)(chs->st), (int)(chs->sat));
|
||||
}
|
||||
}
|
||||
|
||||
@ -476,15 +469,13 @@ static int create_new_connected_udp_socket(dtls_listener_relay_server_type *serv
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot bind udp server socket to device %s\n", (char *)(s->e->relay_ifname));
|
||||
}
|
||||
|
||||
ioa_socket_handle ret = (ioa_socket *)malloc(sizeof(ioa_socket));
|
||||
ioa_socket_handle ret = (ioa_socket *)calloc(1, sizeof(ioa_socket));
|
||||
if (!ret) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot allocate new socket structure\n", __FUNCTION__);
|
||||
socket_closesocket(udp_fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(ret, 0, sizeof(ioa_socket));
|
||||
|
||||
ret->magic = SOCKET_MAGIC;
|
||||
|
||||
ret->fd = udp_fd;
|
||||
@ -553,14 +544,8 @@ static int create_new_connected_udp_socket(dtls_listener_relay_server_type *serv
|
||||
SSL_set_bio(connecting_ssl, NULL, wbio);
|
||||
|
||||
SSL_set_options(connecting_ssl, SSL_OP_COOKIE_EXCHANGE
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if defined(SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS)
|
||||
| SSL3_FLAGS_NO_RENEGOTIATE_CIPHERS
|
||||
#endif
|
||||
#else
|
||||
#if defined(SSL_OP_NO_RENEGOTIATION)
|
||||
| SSL_OP_NO_RENEGOTIATION
|
||||
#endif
|
||||
#endif
|
||||
);
|
||||
|
||||
@ -593,6 +578,11 @@ static int create_new_connected_udp_socket(dtls_listener_relay_server_type *serv
|
||||
}
|
||||
|
||||
static void udp_server_input_handler(evutil_socket_t fd, short what, void *arg) {
|
||||
|
||||
if (!arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
int cycle = 0;
|
||||
|
||||
dtls_listener_relay_server_type *server = (dtls_listener_relay_server_type *)arg;
|
||||
@ -730,8 +720,9 @@ start_udp_cycle:
|
||||
ioa_network_buffer_delete(server->e, server->sm.m.sm.nd.nbh);
|
||||
server->sm.m.sm.nd.nbh = NULL;
|
||||
|
||||
if ((bsize > 0) && (cycle++ < MAX_SINGLE_UDP_BATCH))
|
||||
if ((bsize > 0) && (cycle++ < MAX_SINGLE_UDP_BATCH)) {
|
||||
goto start_udp_cycle;
|
||||
}
|
||||
|
||||
FUNCEND;
|
||||
}
|
||||
@ -742,8 +733,9 @@ static int create_server_socket(dtls_listener_relay_server_type *server, int rep
|
||||
|
||||
FUNCSTART;
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
clean_server(server);
|
||||
|
||||
@ -768,9 +760,6 @@ static int create_server_socket(dtls_listener_relay_server_type *server, int rep
|
||||
set_raw_socket_ttl_options(udp_listen_fd, server->addr.ss.sa_family);
|
||||
set_raw_socket_tos_options(udp_listen_fd, server->addr.ss.sa_family);
|
||||
|
||||
// Signal change to add cpu pinning
|
||||
set_raw_socket_incoming_cpu(udp_listen_fd, server->ts->id);
|
||||
|
||||
{
|
||||
const int max_binding_time = 60;
|
||||
int addr_bind_cycle = 0;
|
||||
@ -799,12 +788,13 @@ static int create_server_socket(dtls_listener_relay_server_type *server, int rep
|
||||
}
|
||||
|
||||
if (report_creation) {
|
||||
if (!turn_params.no_udp && !turn_params.no_dtls)
|
||||
if (!turn_params.no_udp && !turn_params.no_dtls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "DTLS/UDP listener opened on");
|
||||
else if (!turn_params.no_dtls)
|
||||
} else if (!turn_params.no_dtls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "DTLS listener opened on");
|
||||
else if (!turn_params.no_udp)
|
||||
} else if (!turn_params.no_udp) {
|
||||
addr_debug_print(server->verbose, &server->addr, "UDP listener opened on");
|
||||
}
|
||||
}
|
||||
|
||||
FUNCEND;
|
||||
@ -815,8 +805,9 @@ static int create_server_socket(dtls_listener_relay_server_type *server, int rep
|
||||
static int reopen_server_socket(dtls_listener_relay_server_type *server, evutil_socket_t fd) {
|
||||
UNUSED_ARG(fd);
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
FUNCSTART;
|
||||
|
||||
@ -866,12 +857,13 @@ static int reopen_server_socket(dtls_listener_relay_server_type *server, evutil_
|
||||
event_add(server->udp_listen_ev, NULL);
|
||||
}
|
||||
|
||||
if (!turn_params.no_udp && !turn_params.no_dtls)
|
||||
if (!turn_params.no_udp && !turn_params.no_dtls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "DTLS/UDP listener opened on ");
|
||||
else if (!turn_params.no_dtls)
|
||||
} else if (!turn_params.no_dtls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "DTLS listener opened on ");
|
||||
else if (!turn_params.no_udp)
|
||||
} else if (!turn_params.no_udp) {
|
||||
addr_debug_print(server->verbose, &server->addr, "UDP listener opened on ");
|
||||
}
|
||||
|
||||
FUNCEND;
|
||||
|
||||
@ -885,8 +877,9 @@ static int dtls_verify_callback(int ok, X509_STORE_CTX *ctx) {
|
||||
* if he trusts the received certificate.
|
||||
* Here we always trust.
|
||||
*/
|
||||
if (ok && ctx)
|
||||
if (ok && ctx) {
|
||||
return 1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -896,14 +889,16 @@ static int init_server(dtls_listener_relay_server_type *server, const char *ifna
|
||||
int verbose, ioa_engine_handle e, turn_turnserver *ts, int report_creation,
|
||||
ioa_engine_new_connection_event_handler send_socket) {
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
server->ts = ts;
|
||||
server->connect_cb = send_socket;
|
||||
|
||||
if (ifname)
|
||||
if (ifname) {
|
||||
STRCPY(server->ifname, ifname);
|
||||
}
|
||||
|
||||
if (make_ioa_addr((const uint8_t *)local_address, port, &server->addr) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create a DTLS/UDP listener for address: %s\n", local_address);
|
||||
@ -932,8 +927,9 @@ static int clean_server(dtls_listener_relay_server_type *server) {
|
||||
|
||||
#if DTLS_SUPPORTED
|
||||
void setup_dtls_callbacks(SSL_CTX *ctx) {
|
||||
if (!ctx)
|
||||
if (!ctx) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(REQUEST_CLIENT_CERT)
|
||||
/* If client has to authenticate, then */
|
||||
@ -961,16 +957,18 @@ dtls_listener_relay_server_type *create_dtls_listener_server(const char *ifname,
|
||||
}
|
||||
|
||||
ioa_engine_handle get_engine(dtls_listener_relay_server_type *server) {
|
||||
if (server)
|
||||
if (server) {
|
||||
return server->e;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//////////// UDP send ////////////////
|
||||
|
||||
void udp_send_message(dtls_listener_relay_server_type *server, ioa_network_buffer_handle nbh, ioa_addr *dest) {
|
||||
if (server && dest && nbh && (server->udp_listen_s))
|
||||
if (server && dest && nbh && (server->udp_listen_s)) {
|
||||
udp_send(server->udp_listen_s, dest, (char *)ioa_network_buffer_data(nbh), (int)ioa_network_buffer_get_size(nbh));
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -50,6 +50,7 @@ struct redisLibeventEvents {
|
||||
int rev_set, wev_set;
|
||||
char *ip;
|
||||
int port;
|
||||
char *user;
|
||||
char *pwd;
|
||||
int db;
|
||||
};
|
||||
@ -71,7 +72,7 @@ static int redis_le_valid(struct redisLibeventEvents *e) { return (e && !(e->inv
|
||||
|
||||
/////////////////// Callbacks ////////////////////////////
|
||||
|
||||
static void redisLibeventReadEvent(int fd, short event, void *arg) {
|
||||
static void redisLibeventReadEvent(evutil_socket_t fd, short event, void *arg) {
|
||||
((void)fd);
|
||||
((void)event);
|
||||
struct redisLibeventEvents *e = (struct redisLibeventEvents *)arg;
|
||||
@ -84,7 +85,7 @@ static void redisLibeventReadEvent(int fd, short event, void *arg) {
|
||||
} while ((len < 0) && socket_eintr());
|
||||
if (len < 1) {
|
||||
e->invalid = 1;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: e=0x%lx\n", __FUNCTION__, ((unsigned long)e));
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: e=0x%p\n", __FUNCTION__, e);
|
||||
}
|
||||
}
|
||||
if (redis_le_valid(e)) {
|
||||
@ -95,7 +96,7 @@ static void redisLibeventReadEvent(int fd, short event, void *arg) {
|
||||
}
|
||||
}
|
||||
|
||||
static void redisLibeventWriteEvent(int fd, short event, void *arg) {
|
||||
static void redisLibeventWriteEvent(evutil_socket_t fd, short event, void *arg) {
|
||||
((void)fd);
|
||||
((void)event);
|
||||
struct redisLibeventEvents *e = (struct redisLibeventEvents *)arg;
|
||||
@ -143,15 +144,17 @@ static void redisLibeventCleanup(void *privdata) {
|
||||
struct redisLibeventEvents *e = (struct redisLibeventEvents *)privdata;
|
||||
if (e->allocated) {
|
||||
if (e->rev) {
|
||||
if (e->rev_set)
|
||||
if (e->rev_set) {
|
||||
event_del(e->rev);
|
||||
}
|
||||
event_free(e->rev);
|
||||
e->rev = NULL;
|
||||
}
|
||||
e->rev_set = 0;
|
||||
if (e->wev) {
|
||||
if (e->wev_set)
|
||||
if (e->wev_set) {
|
||||
event_del(e->wev);
|
||||
}
|
||||
event_free(e->wev);
|
||||
e->wev = NULL;
|
||||
}
|
||||
@ -166,8 +169,9 @@ static void redisLibeventCleanup(void *privdata) {
|
||||
int is_redis_asyncconn_good(redis_context_handle rch) {
|
||||
if (rch) {
|
||||
struct redisLibeventEvents *e = (struct redisLibeventEvents *)rch;
|
||||
if (redis_le_valid(e))
|
||||
if (redis_le_valid(e)) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -201,8 +205,7 @@ void send_message_to_redis(redis_context_handle rch, const char *command, const
|
||||
|
||||
if ((redisAsyncCommand(ac, NULL, e, rm.format, rm.arg) != REDIS_OK)) {
|
||||
e->invalid = 1;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: ac=0x%lx, e=0x%lx\n", __FUNCTION__,
|
||||
(unsigned long)ac, (unsigned long)e);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Redis connection broken: ac=0x%p, e=0x%p\n", __FUNCTION__, ac, e);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -210,22 +213,21 @@ void send_message_to_redis(redis_context_handle rch, const char *command, const
|
||||
|
||||
///////////////////////// Attach /////////////////////////////////
|
||||
|
||||
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *pwd, int db) {
|
||||
|
||||
struct redisLibeventEvents *e = NULL;
|
||||
redisAsyncContext *ac = NULL;
|
||||
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int port0, char *user, char *pwd, int db) {
|
||||
|
||||
char ip[256];
|
||||
if (ip0 && ip0[0])
|
||||
if (ip0 && ip0[0]) {
|
||||
STRCPY(ip, ip0);
|
||||
else
|
||||
} else {
|
||||
strncpy(ip, "127.0.0.1", sizeof(ip));
|
||||
}
|
||||
|
||||
int port = DEFAULT_REDIS_PORT;
|
||||
if (port0 > 0)
|
||||
if (port0 > 0) {
|
||||
port = port0;
|
||||
}
|
||||
|
||||
ac = redisAsyncConnect(ip, port);
|
||||
redisAsyncContext *ac = redisAsyncConnect(ip, port);
|
||||
if (!ac) {
|
||||
fprintf(stderr, "Error: redisAsyncConnect returned NULL\n");
|
||||
return NULL;
|
||||
@ -235,16 +237,22 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
|
||||
}
|
||||
|
||||
/* Create container for context and r/w events */
|
||||
e = (struct redisLibeventEvents *)malloc(sizeof(struct redisLibeventEvents));
|
||||
memset(e, 0, sizeof(struct redisLibeventEvents));
|
||||
struct redisLibeventEvents *e = (struct redisLibeventEvents *)calloc(1, sizeof(struct redisLibeventEvents));
|
||||
if (!e) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
e->allocated = 1;
|
||||
e->context = ac;
|
||||
e->base = base;
|
||||
e->ip = strdup(ip);
|
||||
e->port = port;
|
||||
if (pwd)
|
||||
if (user) {
|
||||
e->user = strdup(user);
|
||||
}
|
||||
if (pwd) {
|
||||
e->pwd = strdup(pwd);
|
||||
}
|
||||
e->db = db;
|
||||
|
||||
/* Register functions to start/stop listening for events */
|
||||
@ -270,9 +278,15 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
|
||||
e->wev_set = 1;
|
||||
|
||||
// Authentication
|
||||
if (redis_le_valid(e) && pwd) {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s", pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
if (redis_le_valid(e) && pwd && strlen(pwd)) {
|
||||
if (user && strlen(user)) {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s %s", e->user, e->pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
}
|
||||
} else {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -286,20 +300,23 @@ redis_context_handle redisLibeventAttach(struct event_base *base, char *ip0, int
|
||||
}
|
||||
|
||||
static void redis_reconnect(struct redisLibeventEvents *e) {
|
||||
if (!e || !(e->allocated))
|
||||
if (!e || !(e->allocated)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (e->rev) {
|
||||
if (e->rev_set)
|
||||
if (e->rev_set) {
|
||||
event_del(e->rev);
|
||||
}
|
||||
event_free(e->rev);
|
||||
e->rev = NULL;
|
||||
}
|
||||
e->rev_set = 0;
|
||||
|
||||
if (e->wev) {
|
||||
if (e->wev_set)
|
||||
if (e->wev_set) {
|
||||
event_del(e->wev);
|
||||
}
|
||||
event_free(e->wev);
|
||||
e->wev = NULL;
|
||||
}
|
||||
@ -342,9 +359,15 @@ static void redis_reconnect(struct redisLibeventEvents *e) {
|
||||
e->invalid = 0;
|
||||
|
||||
// Authentication
|
||||
if (redis_le_valid(e) && e->pwd) {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
if (redis_le_valid(e) && e->pwd && strlen(e->pwd)) {
|
||||
if (e->user && strlen(e->user)) {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s %s", e->user, e->pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
}
|
||||
} else {
|
||||
if (redisAsyncCommand(ac, NULL, e, "AUTH %s", e->pwd) != REDIS_OK) {
|
||||
e->invalid = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,7 +48,7 @@ typedef void *redis_context_handle;
|
||||
|
||||
#if !defined(TURN_NO_HIREDIS)
|
||||
|
||||
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *pwd, int db);
|
||||
redis_context_handle redisLibeventAttach(struct event_base *base, char *ip, int port, char *user, char *pwd, int db);
|
||||
|
||||
void send_message_to_redis(redis_context_handle rch, const char *command, const char *key, const char *format, ...);
|
||||
|
||||
@ -119,9 +119,9 @@ static struct headers_list *post_parse(char *data, size_t data_len) {
|
||||
while (fsplit != NULL) {
|
||||
char *vmarker = NULL;
|
||||
char *key = strtok_r(fsplit, "=", &vmarker);
|
||||
if (key == NULL)
|
||||
if (key == NULL) {
|
||||
break;
|
||||
else {
|
||||
} else {
|
||||
char *value = strtok_r(NULL, "=", &vmarker);
|
||||
char empty[1];
|
||||
empty[0] = 0;
|
||||
@ -129,8 +129,9 @@ static struct headers_list *post_parse(char *data, size_t data_len) {
|
||||
value = evhttp_decode_uri(value);
|
||||
char *p = value;
|
||||
while (*p) {
|
||||
if (*p == '+')
|
||||
if (*p == '+') {
|
||||
*p = ' ';
|
||||
}
|
||||
p++;
|
||||
}
|
||||
list->keys = (char **)realloc(list->keys, sizeof(char *) * (list->n + 1));
|
||||
@ -171,6 +172,10 @@ static struct http_request *parse_http_request_1(struct http_request *ret, char
|
||||
if (evhttp_parse_query_str(query, kv) < 0) {
|
||||
free(ret);
|
||||
ret = NULL;
|
||||
if (kv) {
|
||||
// kv no longer assigned on this path
|
||||
free(kv);
|
||||
}
|
||||
} else {
|
||||
ret->headers = (struct http_headers *)calloc(sizeof(struct http_headers), 1);
|
||||
ret->headers->uri_headers = kv;
|
||||
@ -178,8 +183,9 @@ static struct http_request *parse_http_request_1(struct http_request *ret, char
|
||||
}
|
||||
|
||||
const char *path = evhttp_uri_get_path(uri);
|
||||
if (path && ret)
|
||||
if (path && ret) {
|
||||
ret->path = strdup(path);
|
||||
}
|
||||
|
||||
evhttp_uri_free(uri);
|
||||
|
||||
@ -325,8 +331,14 @@ struct str_buffer {
|
||||
|
||||
struct str_buffer *str_buffer_new(void) {
|
||||
struct str_buffer *ret = (struct str_buffer *)calloc(sizeof(struct str_buffer), 1);
|
||||
|
||||
if (!ret) {
|
||||
return NULL;
|
||||
}
|
||||
ret->buffer = (char *)malloc(1);
|
||||
if (!(ret->buffer)) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->buffer[0] = 0;
|
||||
ret->capacity = 1;
|
||||
return ret;
|
||||
|
||||
@ -11,9 +11,6 @@
|
||||
* all present and future rights to this code under copyright law.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
@ -21,7 +18,7 @@
|
||||
#include <string.h>
|
||||
|
||||
/* Win32 compatibility */
|
||||
#if defined(WINDOWS)
|
||||
#if defined(_WIN32)
|
||||
#define vsnprintf _vsnprintf
|
||||
#define __func__ __FUNCTION__
|
||||
#define ZLIB_WINAPI 1
|
||||
@ -170,12 +167,14 @@ telnet_error_t _init_zlib(telnet_t *telnet, int deflate, int err_fatal) {
|
||||
int rs;
|
||||
|
||||
/* if compression is already enabled, fail loudly */
|
||||
if (telnet->z != 0)
|
||||
if (telnet->z != 0) {
|
||||
return telnet_error(telnet, __LINE__, __func__, TELNET_EBADVAL, err_fatal, "cannot initialize compression twice");
|
||||
}
|
||||
|
||||
/* allocate zstream box */
|
||||
if ((z = (z_stream *)calloc(1, sizeof(z_stream))) == 0)
|
||||
if ((z = (z_stream *)calloc(1, sizeof(z_stream))) == 0) {
|
||||
return telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, err_fatal, "malloc() failed: %s", strerror(errno));
|
||||
}
|
||||
|
||||
/* initialize */
|
||||
if (deflate) {
|
||||
@ -260,18 +259,20 @@ static INLINE int _check_telopt(telnet_t *telnet, unsigned char telopt, int us)
|
||||
int i;
|
||||
|
||||
/* if we have no telopts table, we obviously don't support it */
|
||||
if (telnet->telopts == 0)
|
||||
if (telnet->telopts == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* loop until found or end marker (us and him both 0) */
|
||||
for (i = 0; telnet->telopts[i].telopt != -1; ++i) {
|
||||
if (telnet->telopts[i].telopt == telopt) {
|
||||
if (us && telnet->telopts[i].us == TELNET_WILL)
|
||||
if (us && telnet->telopts[i].us == TELNET_WILL) {
|
||||
return 1;
|
||||
else if (!us && telnet->telopts[i].him == TELNET_DO)
|
||||
} else if (!us && telnet->telopts[i].him == TELNET_DO) {
|
||||
return 1;
|
||||
else
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -306,13 +307,16 @@ static INLINE void _set_rfc1143(telnet_t *telnet, unsigned char telopt, char us,
|
||||
for (i = 0; i != telnet->q_cnt; ++i) {
|
||||
if (telnet->q[i].telopt == telopt) {
|
||||
telnet->q[i].state = Q_MAKE(us, him);
|
||||
if (telopt != TELNET_TELOPT_BINARY)
|
||||
if (telopt != TELNET_TELOPT_BINARY) {
|
||||
return;
|
||||
}
|
||||
telnet->flags &= ~(TELNET_FLAG_TRANSMIT_BINARY | TELNET_FLAG_RECEIVE_BINARY);
|
||||
if (us == Q_YES)
|
||||
if (us == Q_YES) {
|
||||
telnet->flags |= TELNET_FLAG_TRANSMIT_BINARY;
|
||||
if (him == Q_YES)
|
||||
}
|
||||
if (him == Q_YES) {
|
||||
telnet->flags |= TELNET_FLAG_RECEIVE_BINARY;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -388,8 +392,9 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
_set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
|
||||
_send_negotiate(telnet, TELNET_DO, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
|
||||
} else
|
||||
} else {
|
||||
_send_negotiate(telnet, TELNET_DONT, telopt);
|
||||
}
|
||||
break;
|
||||
case Q_WANTNO:
|
||||
_set_rfc1143(telnet, telopt, Q_US(q), Q_NO);
|
||||
@ -398,7 +403,6 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
break;
|
||||
case Q_WANTNO_OP:
|
||||
_set_rfc1143(telnet, telopt, Q_US(q), Q_YES);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "DONT answered by WILL");
|
||||
break;
|
||||
case Q_WANTYES:
|
||||
@ -427,7 +431,8 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
break;
|
||||
case Q_WANTNO_OP:
|
||||
_set_rfc1143(telnet, telopt, Q_US(q), Q_WANTYES);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
|
||||
_send_negotiate(telnet, TELNET_DO, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
|
||||
break;
|
||||
case Q_WANTYES:
|
||||
case Q_WANTYES_OP:
|
||||
@ -444,8 +449,9 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
_set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
|
||||
_send_negotiate(telnet, TELNET_WILL, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
|
||||
} else
|
||||
} else {
|
||||
_send_negotiate(telnet, TELNET_WONT, telopt);
|
||||
}
|
||||
break;
|
||||
case Q_WANTNO:
|
||||
_set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
|
||||
@ -454,7 +460,6 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
break;
|
||||
case Q_WANTNO_OP:
|
||||
_set_rfc1143(telnet, telopt, Q_YES, Q_HIM(q));
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_DO, telopt);
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_EPROTOCOL, 0, "WONT answered by DO");
|
||||
break;
|
||||
case Q_WANTYES:
|
||||
@ -479,12 +484,12 @@ static void _negotiate(telnet_t *telnet, unsigned char telopt) {
|
||||
break;
|
||||
case Q_WANTNO:
|
||||
_set_rfc1143(telnet, telopt, Q_NO, Q_HIM(q));
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_WONT, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
|
||||
break;
|
||||
case Q_WANTNO_OP:
|
||||
_set_rfc1143(telnet, telopt, Q_WANTYES, Q_HIM(q));
|
||||
_send_negotiate(telnet, TELNET_WILL, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_WILL, telopt);
|
||||
NEGOTIATE_EVENT(telnet, TELNET_EV_DONT, telopt);
|
||||
break;
|
||||
case Q_WANTYES:
|
||||
case Q_WANTYES_OP:
|
||||
@ -538,7 +543,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, char *buffer, s
|
||||
ev.type = TELNET_EV_ENVIRON;
|
||||
telnet->eh(telnet, &ev, telnet->ud);
|
||||
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* very second byte must be VAR or USERVAR, if present */
|
||||
@ -635,7 +640,7 @@ static int _environ_telnet(telnet_t *telnet, unsigned char type, char *buffer, s
|
||||
|
||||
/* clean up */
|
||||
free(values);
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* process an MSSP subnegotiation buffer */
|
||||
@ -715,7 +720,7 @@ static int _mssp_telnet(telnet_t *telnet, char *buffer, size_t size) {
|
||||
/* parse ZMP command subnegotiation buffers */
|
||||
static int _zmp_telnet(telnet_t *telnet, const char *buffer, size_t size) {
|
||||
telnet_event_t ev;
|
||||
const char **argv;
|
||||
char **argv;
|
||||
const char *c;
|
||||
size_t i, argc;
|
||||
|
||||
@ -726,24 +731,25 @@ static int _zmp_telnet(telnet_t *telnet, const char *buffer, size_t size) {
|
||||
}
|
||||
|
||||
/* count arguments */
|
||||
for (argc = 0, c = buffer; c != buffer + size; ++argc)
|
||||
for (argc = 0, c = buffer; c != buffer + size; ++argc) {
|
||||
c += strlen(c) + 1;
|
||||
}
|
||||
|
||||
/* allocate argument array, bail on error */
|
||||
if ((argv = (const char **)calloc(argc, sizeof(const char *))) == 0) {
|
||||
if ((argv = (char **)calloc(argc, sizeof(char *))) == 0) {
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "calloc() failed: %s", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* populate argument array */
|
||||
for (i = 0, c = buffer; i != argc; ++i) {
|
||||
argv[i] = c;
|
||||
argv[i] = (char *)c;
|
||||
c += strlen(c) + 1;
|
||||
}
|
||||
|
||||
/* invoke event with our arguments */
|
||||
ev.type = TELNET_EV_ZMP;
|
||||
ev.zmp.argv = argv;
|
||||
ev.zmp.argv = (const char **)argv;
|
||||
ev.zmp.argc = argc;
|
||||
telnet->eh(telnet, &ev, telnet->ud);
|
||||
|
||||
@ -816,17 +822,15 @@ static int _subnegotiate(telnet_t *telnet) {
|
||||
* start handling the compressed stream if it's not already.
|
||||
*/
|
||||
case TELNET_TELOPT_COMPRESS2:
|
||||
if (telnet->sb_telopt == TELNET_TELOPT_COMPRESS2) {
|
||||
if (_init_zlib(telnet, 0, 1) != TELNET_EOK)
|
||||
return 0;
|
||||
|
||||
/* notify app that compression was enabled */
|
||||
ev.type = TELNET_EV_COMPRESS;
|
||||
ev.compress.state = 1;
|
||||
telnet->eh(telnet, &ev, telnet->ud);
|
||||
return 1;
|
||||
if (_init_zlib(telnet, 0, 1) != TELNET_EOK) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
/* notify app that compression was enabled */
|
||||
ev.type = TELNET_EV_COMPRESS;
|
||||
ev.compress.state = 1;
|
||||
telnet->eh(telnet, &ev, telnet->ud);
|
||||
return 1;
|
||||
#endif /* defined(HAVE_ZLIB) */
|
||||
|
||||
/* specially handled subnegotiation telopt types */
|
||||
@ -848,8 +852,9 @@ static int _subnegotiate(telnet_t *telnet) {
|
||||
telnet_t *telnet_init(const telnet_telopt_t *telopts, telnet_event_handler_t eh, unsigned char flags, void *user_data) {
|
||||
/* allocate structure */
|
||||
struct telnet_t *telnet = (telnet_t *)calloc(1, sizeof(telnet_t));
|
||||
if (telnet == 0)
|
||||
if (telnet == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* initialize data */
|
||||
telnet->ud = user_data;
|
||||
@ -873,10 +878,11 @@ void telnet_free(telnet_t *telnet) {
|
||||
#if defined(HAVE_ZLIB)
|
||||
/* free zlib box */
|
||||
if (telnet->z != 0) {
|
||||
if (telnet->flags & TELNET_PFLAG_DEFLATE)
|
||||
if (telnet->flags & TELNET_PFLAG_DEFLATE) {
|
||||
deflateEnd(telnet->z);
|
||||
else
|
||||
} else {
|
||||
inflateEnd(telnet->z);
|
||||
}
|
||||
free(telnet->z);
|
||||
telnet->z = 0;
|
||||
}
|
||||
@ -971,11 +977,12 @@ static void _process(telnet_t *telnet, const char *buffer, size_t size) {
|
||||
telnet->eh(telnet, &ev, telnet->ud);
|
||||
byte = buffer[i];
|
||||
}
|
||||
// any byte following '\r' other than '\n' or '\0' is invalid,
|
||||
// so pass both \r and the byte
|
||||
/* any byte following '\r' other than '\n' or '\0' is invalid,
|
||||
* so pass both \r and the byte */
|
||||
start = i;
|
||||
if (byte == '\0')
|
||||
if (byte == '\0') {
|
||||
++start;
|
||||
}
|
||||
/* state update */
|
||||
telnet->state = TELNET_STATE_DATA;
|
||||
break;
|
||||
@ -1155,10 +1162,11 @@ void telnet_recv(telnet_t *telnet, const char *buffer, size_t size) {
|
||||
rs = inflate(telnet->z, Z_SYNC_FLUSH);
|
||||
|
||||
/* process the decompressed bytes on success */
|
||||
if (rs == Z_OK || rs == Z_STREAM_END)
|
||||
if (rs == Z_OK || rs == Z_STREAM_END) {
|
||||
_process(telnet, inflate_buffer, sizeof(inflate_buffer) - telnet->z->avail_out);
|
||||
else
|
||||
} else {
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_ECOMPRESS, 1, "inflate() failed: %s", zError(rs));
|
||||
}
|
||||
|
||||
/* prepare output buffer for next run */
|
||||
telnet->z->next_out = (unsigned char *)inflate_buffer;
|
||||
@ -1374,8 +1382,9 @@ void telnet_subnegotiation(telnet_t *telnet, unsigned char telopt, const char *b
|
||||
if (telnet->flags & TELNET_FLAG_PROXY && telopt == TELNET_TELOPT_COMPRESS2) {
|
||||
telnet_event_t ev;
|
||||
|
||||
if (_init_zlib(telnet, 1, 1) != TELNET_EOK)
|
||||
if (_init_zlib(telnet, 1, 1) != TELNET_EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* notify app that compression was enabled */
|
||||
ev.type = TELNET_EV_COMPRESS;
|
||||
@ -1392,8 +1401,9 @@ void telnet_begin_compress2(telnet_t *telnet) {
|
||||
telnet_event_t ev;
|
||||
|
||||
/* attempt to create output stream first, bail if we can't */
|
||||
if (_init_zlib(telnet, 1, 0) != TELNET_EOK)
|
||||
if (_init_zlib(telnet, 1, 0) != TELNET_EOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
/* send compression marker. we send directly to the event handler
|
||||
* instead of passing through _send because _send would result in
|
||||
@ -1415,43 +1425,50 @@ void telnet_begin_compress2(telnet_t *telnet) {
|
||||
|
||||
/* send formatted data with \r and \n translation in addition to IAC IAC */
|
||||
int telnet_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
|
||||
va_list va_temp;
|
||||
char buffer[1024];
|
||||
char *output = buffer;
|
||||
unsigned int rs, i, l;
|
||||
|
||||
/* format */
|
||||
va_list va2;
|
||||
va_copy(va2, va);
|
||||
rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
|
||||
va_copy(va_temp, va);
|
||||
rs = vsnprintf(buffer, sizeof(buffer), fmt, va_temp);
|
||||
va_end(va_temp);
|
||||
|
||||
if (rs >= sizeof(buffer)) {
|
||||
output = (char *)malloc(rs + 1);
|
||||
if (output == 0) {
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno));
|
||||
va_end(va2);
|
||||
return -1;
|
||||
}
|
||||
rs = vsnprintf(output, rs + 1, fmt, va2);
|
||||
|
||||
va_copy(va_temp, va);
|
||||
rs = vsnprintf(output, rs + 1, fmt, va_temp);
|
||||
va_end(va_temp);
|
||||
}
|
||||
va_end(va2);
|
||||
|
||||
/* send */
|
||||
for (l = i = 0; i != rs; ++i) {
|
||||
/* special characters */
|
||||
if (output[i] == (char)TELNET_IAC || output[i] == '\r' || output[i] == '\n') {
|
||||
/* dump prior portion of text */
|
||||
if (i != l)
|
||||
if (i != l) {
|
||||
_send(telnet, output + l, i - l);
|
||||
}
|
||||
l = i + 1;
|
||||
|
||||
/* IAC -> IAC IAC */
|
||||
if (output[i] == (char)TELNET_IAC)
|
||||
if (output[i] == (char)TELNET_IAC) {
|
||||
telnet_iac(telnet, TELNET_IAC);
|
||||
}
|
||||
/* automatic translation of \r -> CRNUL */
|
||||
else if (output[i] == '\r')
|
||||
else if (output[i] == '\r') {
|
||||
_send(telnet, CRNUL, 2);
|
||||
}
|
||||
/* automatic translation of \n -> CRLF */
|
||||
else if (output[i] == '\n')
|
||||
else if (output[i] == '\n') {
|
||||
_send(telnet, CRLF, 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1482,24 +1499,27 @@ int telnet_printf(telnet_t *telnet, const char *fmt, ...) {
|
||||
|
||||
/* send formatted data through telnet_send */
|
||||
int telnet_raw_vprintf(telnet_t *telnet, const char *fmt, va_list va) {
|
||||
va_list va_temp;
|
||||
char buffer[1024];
|
||||
char *output = buffer;
|
||||
unsigned int rs;
|
||||
|
||||
/* format; allocate more space if necessary */
|
||||
va_list va2;
|
||||
va_copy(va2, va);
|
||||
rs = vsnprintf(buffer, sizeof(buffer), fmt, va);
|
||||
va_copy(va_temp, va);
|
||||
rs = vsnprintf(buffer, sizeof(buffer), fmt, va_temp);
|
||||
va_end(va_temp);
|
||||
|
||||
if (rs >= sizeof(buffer)) {
|
||||
output = (char *)malloc(rs + 1);
|
||||
if (output == 0) {
|
||||
telnet_error(telnet, __LINE__, __func__, TELNET_ENOMEM, 0, "malloc() failed: %s", strerror(errno));
|
||||
va_end(va2);
|
||||
return -1;
|
||||
}
|
||||
rs = vsnprintf(output, rs + 1, fmt, va2);
|
||||
|
||||
va_copy(va_temp, va);
|
||||
rs = vsnprintf(output, rs + 1, fmt, va_temp);
|
||||
va_end(va_temp);
|
||||
}
|
||||
va_end(va2);
|
||||
|
||||
/* send out the formatted data */
|
||||
telnet_send(telnet, output, rs);
|
||||
@ -1549,6 +1569,9 @@ void telnet_ttype_send(telnet_t *telnet) {
|
||||
/* send TERMINAL-TYPE IS command */
|
||||
void telnet_ttype_is(telnet_t *telnet, const char *ttype) {
|
||||
static const unsigned char IS[] = {TELNET_IAC, TELNET_SB, TELNET_TELOPT_TTYPE, TELNET_TTYPE_IS};
|
||||
if (!ttype) {
|
||||
ttype = "NVT";
|
||||
}
|
||||
_sendu(telnet, IS, sizeof(IS));
|
||||
_send(telnet, ttype, strlen(ttype));
|
||||
telnet_finish_sb(telnet);
|
||||
@ -1562,8 +1585,9 @@ void telnet_send_zmp(telnet_t *telnet, size_t argc, const char **argv) {
|
||||
telnet_begin_zmp(telnet, argv[0]);
|
||||
|
||||
/* send out each argument, including trailing NUL byte */
|
||||
for (i = 1; i != argc; ++i)
|
||||
for (i = 1; i != argc; ++i) {
|
||||
telnet_zmp_arg(telnet, argv[i]);
|
||||
}
|
||||
|
||||
/* ZMP footer */
|
||||
telnet_finish_zmp(telnet);
|
||||
@ -1577,8 +1601,9 @@ void telnet_send_vzmpv(telnet_t *telnet, va_list va) {
|
||||
telnet_begin_sb(telnet, TELNET_TELOPT_ZMP);
|
||||
|
||||
/* send out each argument, including trailing NUL byte */
|
||||
while ((arg = va_arg(va, const char *)) != 0)
|
||||
while ((arg = va_arg(va, const char *)) != 0) {
|
||||
telnet_zmp_arg(telnet, arg);
|
||||
}
|
||||
|
||||
/* ZMP footer */
|
||||
telnet_finish_zmp(telnet);
|
||||
|
||||
@ -252,7 +252,7 @@ union telnet_event_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
const char *buffer; /*!< byte buffer */
|
||||
size_t size; /*!< number of bytes in buffer */
|
||||
} data;
|
||||
} data; /*!< DATA and SEND */
|
||||
|
||||
/*!
|
||||
* WARNING and ERROR events
|
||||
@ -264,7 +264,7 @@ union telnet_event_t {
|
||||
const char *msg; /*!< error message string */
|
||||
int line; /*!< line of file error occured on */
|
||||
telnet_error_t errcode; /*!< error code */
|
||||
} error;
|
||||
} error; /*!< WARNING and ERROR */
|
||||
|
||||
/*!
|
||||
* command event: for IAC
|
||||
@ -272,7 +272,7 @@ union telnet_event_t {
|
||||
struct iac_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
unsigned char cmd; /*!< telnet command received */
|
||||
} iac;
|
||||
} iac; /*!< IAC */
|
||||
|
||||
/*!
|
||||
* negotiation event: WILL, WONT, DO, DONT
|
||||
@ -280,7 +280,7 @@ union telnet_event_t {
|
||||
struct negotiate_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
unsigned char telopt; /*!< option being negotiated */
|
||||
} neg;
|
||||
} neg; /*!< WILL, WONT, DO, DONT */
|
||||
|
||||
/*!
|
||||
* subnegotiation event
|
||||
@ -290,7 +290,7 @@ union telnet_event_t {
|
||||
const char *buffer; /*!< data of sub-negotiation */
|
||||
size_t size; /*!< number of bytes in buffer */
|
||||
unsigned char telopt; /*!< option code for negotiation */
|
||||
} sub;
|
||||
} sub; /*!< SB */
|
||||
|
||||
/*!
|
||||
* ZMP event
|
||||
@ -299,7 +299,7 @@ union telnet_event_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
const char **argv; /*!< array of argument string */
|
||||
size_t argc; /*!< number of elements in argv */
|
||||
} zmp;
|
||||
} zmp; /*!< ZMP */
|
||||
|
||||
/*!
|
||||
* TTYPE event
|
||||
@ -308,7 +308,7 @@ union telnet_event_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
unsigned char cmd; /*!< TELNET_TTYPE_IS or TELNET_TTYPE_SEND */
|
||||
const char *name; /*!< terminal type name (IS only) */
|
||||
} ttype;
|
||||
} ttype; /*!< TTYPE */
|
||||
|
||||
/*!
|
||||
* COMPRESS event
|
||||
@ -317,7 +317,7 @@ union telnet_event_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
unsigned char state; /*!< 1 if compression is enabled,
|
||||
0 if disabled */
|
||||
} compress;
|
||||
} compress; /*!< COMPRESS */
|
||||
|
||||
/*!
|
||||
* ENVIRON/NEW-ENVIRON event
|
||||
@ -327,7 +327,7 @@ union telnet_event_t {
|
||||
const struct telnet_environ_t *values; /*!< array of variable values */
|
||||
size_t size; /*!< number of elements in values */
|
||||
unsigned char cmd; /*!< SEND, IS, or INFO */
|
||||
} environ;
|
||||
} environ; /*!< ENVIRON, NEW-ENVIRON */
|
||||
|
||||
/*!
|
||||
* MSSP event
|
||||
@ -336,7 +336,7 @@ union telnet_event_t {
|
||||
enum telnet_event_type_t _type; /*!< alias for type */
|
||||
const struct telnet_environ_t *values; /*!< array of variable values */
|
||||
size_t size; /*!< number of elements in values */
|
||||
} mssp;
|
||||
} mssp; /*!< MSSP */
|
||||
};
|
||||
|
||||
/*!
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -28,10 +28,11 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if !defined(__MAIN_RELAY__)
|
||||
#ifndef __MAIN_RELAY__
|
||||
#define __MAIN_RELAY__
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -86,9 +87,7 @@
|
||||
#include <openssl/pem.h>
|
||||
#include <openssl/ssl.h>
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
#include <openssl/modes.h>
|
||||
#endif
|
||||
|
||||
#if !defined(TURN_NO_SYSTEMD)
|
||||
#include <systemd/sd-daemon.h>
|
||||
@ -104,12 +103,10 @@ extern "C" {
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x30000000L
|
||||
#define DEFAULT_CIPHER_LIST OSSL_default_cipher_list()
|
||||
#if TLSv1_3_SUPPORTED
|
||||
#define DEFAULT_CIPHERSUITES OSSL_default_ciphersuites()
|
||||
#endif
|
||||
#else
|
||||
#define DEFAULT_CIPHER_LIST "DEFAULT"
|
||||
#if TLSv1_3_SUPPORTED && defined(TLS_DEFAULT_CIPHERSUITES)
|
||||
#if defined(TLS_DEFAULT_CIPHERSUITES)
|
||||
#define DEFAULT_CIPHERSUITES TLS_DEFAULT_CIPHERSUITES
|
||||
#endif
|
||||
#endif
|
||||
@ -192,6 +189,7 @@ typedef struct _turn_params_ {
|
||||
char ca_cert_file[1025];
|
||||
char cert_file[1025];
|
||||
char pkey_file[1025];
|
||||
bool rpk_enabled;
|
||||
char tls_password[513];
|
||||
char dh_file[1025];
|
||||
|
||||
@ -208,7 +206,7 @@ typedef struct _turn_params_ {
|
||||
|
||||
int verbose;
|
||||
int turn_daemon;
|
||||
int no_software_attribute;
|
||||
bool software_attribute;
|
||||
int web_admin_listen_on_workers;
|
||||
|
||||
int do_not_use_config_file;
|
||||
@ -284,8 +282,9 @@ typedef struct _turn_params_ {
|
||||
turn_server_addrs_list_t alternate_servers_list;
|
||||
turn_server_addrs_list_t tls_alternate_servers_list;
|
||||
|
||||
/////////////// stop server ////////////////
|
||||
int stop_turn_server;
|
||||
/////////////// stop/drain server ////////////////
|
||||
bool drain_turn_server;
|
||||
bool stop_turn_server;
|
||||
|
||||
////////////// MISC PARAMS ////////////////
|
||||
|
||||
@ -309,6 +308,8 @@ typedef struct _turn_params_ {
|
||||
vint user_quota;
|
||||
int prometheus;
|
||||
int prometheus_port;
|
||||
char prometheus_address[INET6_ADDRSTRLEN];
|
||||
char prometheus_path[1025];
|
||||
int prometheus_username_labels;
|
||||
|
||||
/////// Users DB ///////////
|
||||
@ -338,14 +339,16 @@ extern turn_params_t turn_params;
|
||||
//////////////// Listener server /////////////////
|
||||
|
||||
static inline int get_alt_listener_port(void) {
|
||||
if (turn_params.alt_listener_port < 1)
|
||||
if (turn_params.alt_listener_port < 1) {
|
||||
return turn_params.listener_port + 1;
|
||||
}
|
||||
return turn_params.alt_listener_port;
|
||||
}
|
||||
|
||||
static inline int get_alt_tls_listener_port(void) {
|
||||
if (turn_params.alt_tls_listener_port < 1)
|
||||
if (turn_params.alt_tls_listener_port < 1) {
|
||||
return turn_params.tls_listener_port + 1;
|
||||
}
|
||||
return turn_params.alt_tls_listener_port;
|
||||
}
|
||||
|
||||
@ -373,6 +376,7 @@ void send_auth_message_to_auth_server(struct auth_message *am);
|
||||
void init_listener(void);
|
||||
void setup_server(void);
|
||||
void run_listener_server(struct listener_server *ls);
|
||||
void enable_drain_mode(void);
|
||||
|
||||
////////// BPS ////////////////
|
||||
|
||||
@ -389,7 +393,6 @@ struct ctr_state {
|
||||
unsigned int num;
|
||||
unsigned char ecount[16];
|
||||
};
|
||||
void generate_aes_128_key(char *filePath, unsigned char *returnedKey);
|
||||
unsigned char *base64encode(const void *b64_encode_this, int encode_this_many_bytes);
|
||||
void encrypt_aes_128(unsigned char *in, const unsigned char *mykey);
|
||||
unsigned char *base64decode(const void *b64_decode_this, int decode_this_many_bytes);
|
||||
|
||||
@ -30,9 +30,10 @@
|
||||
|
||||
#include "mainrelay.h"
|
||||
|
||||
#include "ns_turn_ioalib.h"
|
||||
|
||||
//////////// Backward compatibility with OpenSSL 1.0.x //////////////
|
||||
#if (OPENSSL_VERSION_NUMBER < 0x10100001L || \
|
||||
(defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER <= 0x3040000fL))
|
||||
#if defined(LIBRESSL_VERSION_NUMBER) && LIBRESSL_VERSION_NUMBER <= 0x3040000fL
|
||||
#define SSL_CTX_up_ref(ctx) CRYPTO_add(&(ctx)->references, 1, CRYPTO_LOCK_SSL_CTX)
|
||||
#endif
|
||||
|
||||
@ -43,10 +44,6 @@ static unsigned int barrier_count = 0;
|
||||
static pthread_barrier_t barrier;
|
||||
#endif
|
||||
|
||||
// Signal change to add rtt metrics
|
||||
|
||||
static pthread_barrier_t rtt_barrier;
|
||||
|
||||
////////////// Auth Server ////////////////
|
||||
|
||||
typedef unsigned char authserver_id;
|
||||
@ -240,22 +237,22 @@ static void del_alt_server(const char *saddr, int default_port, turn_server_addr
|
||||
} else {
|
||||
|
||||
size_t i;
|
||||
int found = 0;
|
||||
for (i = 0; i < list->size; ++i) {
|
||||
if (addr_eq(&(list->addrs[i]), &addr)) {
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (found) {
|
||||
if (i < list->size) {
|
||||
|
||||
size_t j;
|
||||
ioa_addr *new_addrs = (ioa_addr *)malloc(sizeof(ioa_addr) * (list->size - 1));
|
||||
for (j = 0; j < i; ++j) {
|
||||
if (!new_addrs) {
|
||||
return;
|
||||
}
|
||||
for (size_t j = 0; j < i; ++j) {
|
||||
addr_cpy(&(new_addrs[j]), &(list->addrs[j]));
|
||||
}
|
||||
for (j = i; j < list->size - 1; ++j) {
|
||||
for (size_t j = i; j < list->size - 1; ++j) {
|
||||
addr_cpy(&(new_addrs[j]), &(list->addrs[j + 1]));
|
||||
}
|
||||
|
||||
@ -303,11 +300,13 @@ typedef struct update_ssl_ctx_cb_args {
|
||||
* Copy SSL context at "from", which may be NULL if no context in use
|
||||
*/
|
||||
static void replace_one_ssl_ctx(SSL_CTX **to, SSL_CTX *from) {
|
||||
if (*to)
|
||||
if (*to) {
|
||||
SSL_CTX_free(*to);
|
||||
}
|
||||
|
||||
if (from != NULL)
|
||||
if (from != NULL) {
|
||||
SSL_CTX_up_ref(from);
|
||||
}
|
||||
|
||||
*to = from;
|
||||
}
|
||||
@ -328,8 +327,9 @@ static void update_ssl_ctx(evutil_socket_t sock, short events, update_ssl_ctx_cb
|
||||
struct event *next = args->next;
|
||||
TURN_MUTEX_UNLOCK(&turn_params.tls_mutex);
|
||||
|
||||
if (next != NULL)
|
||||
if (next != NULL) {
|
||||
event_active(next, EV_READ, 0);
|
||||
}
|
||||
|
||||
UNUSED_ARG(sock);
|
||||
UNUSED_ARG(events);
|
||||
@ -350,6 +350,10 @@ void set_ssl_ctx(ioa_engine_handle e, turn_params_t *params) {
|
||||
args->next = params->tls_ctx_update_ev;
|
||||
params->tls_ctx_update_ev = ev;
|
||||
TURN_MUTEX_UNLOCK(&turn_params.tls_mutex);
|
||||
} else {
|
||||
if (args) {
|
||||
free(args);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,10 +467,11 @@ static authserver_id auth_message_counter = 1;
|
||||
|
||||
void send_auth_message_to_auth_server(struct auth_message *am) {
|
||||
TURN_MUTEX_LOCK(&auth_message_counter_mutex);
|
||||
if (auth_message_counter >= authserver_number)
|
||||
if (auth_message_counter >= authserver_number) {
|
||||
auth_message_counter = 1;
|
||||
else if (auth_message_counter < 1)
|
||||
} else if (auth_message_counter < 1) {
|
||||
auth_message_counter = 1;
|
||||
}
|
||||
authserver_id sn = auth_message_counter++;
|
||||
TURN_MUTEX_UNLOCK(&auth_message_counter_mutex);
|
||||
|
||||
@ -508,9 +513,9 @@ static void auth_server_receive_message(struct bufferevent *bev, void *ptr) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__, (int)am.id);
|
||||
}
|
||||
|
||||
if (output)
|
||||
if (output) {
|
||||
evbuffer_add(output, &am, sizeof(struct auth_message));
|
||||
else {
|
||||
} else {
|
||||
ioa_network_buffer_delete(NULL, am.in_buffer.nbh);
|
||||
am.in_buffer.nbh = NULL;
|
||||
}
|
||||
@ -690,37 +695,6 @@ err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Signal change to add rtt metrics
|
||||
int send_cycle_rtt_map_to_relay(turnserver_id id) {
|
||||
int ret = 0;
|
||||
|
||||
struct message_to_relay sm;
|
||||
memset(&sm, 0, sizeof(struct message_to_relay));
|
||||
sm.t = RMT_CYCLE_RTT_MAP;
|
||||
|
||||
struct relay_server *rs = get_relay_server(id);
|
||||
if (!rs) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: can't find relay for turn_server_id: %d\n", __FUNCTION__, (int)id);
|
||||
ret = -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
sm.relay_server = rs;
|
||||
|
||||
{
|
||||
struct evbuffer *output = bufferevent_get_output(rs->out_buf);
|
||||
if (output) {
|
||||
evbuffer_add(output, &sm, sizeof(struct message_to_relay));
|
||||
} else {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Empty output buffer\n", __FUNCTION__);
|
||||
ret = -1;
|
||||
}
|
||||
}
|
||||
|
||||
err:
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int handle_relay_message(relay_server_handle rs, struct message_to_relay *sm) {
|
||||
if (rs && sm) {
|
||||
|
||||
@ -746,8 +720,8 @@ static int handle_relay_message(relay_server_handle rs, struct message_to_relay
|
||||
if (!s) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket EMPTY\n", __FUNCTION__);
|
||||
} else if (s->read_event || s->bev) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket wrongly preset: 0x%lx : 0x%lx\n", __FUNCTION__,
|
||||
(long)s->read_event, (long)s->bev);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: socket wrongly preset: %p : %p\n", __FUNCTION__, s->read_event,
|
||||
s->bev);
|
||||
IOA_CLOSE_SOCKET(s);
|
||||
sm->m.sm.s = NULL;
|
||||
} else {
|
||||
@ -785,8 +759,8 @@ static int handle_relay_message(relay_server_handle rs, struct message_to_relay
|
||||
if (!s) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: mobile socket EMPTY\n", __FUNCTION__);
|
||||
} else if (s->read_event || s->bev) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: mobile socket wrongly preset: 0x%lx : 0x%lx\n", __FUNCTION__,
|
||||
(long)s->read_event, (long)s->bev);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: mobile socket wrongly preset: %p : %p\n", __FUNCTION__, s->read_event,
|
||||
s->bev);
|
||||
IOA_CLOSE_SOCKET(s);
|
||||
sm->m.sm.s = NULL;
|
||||
} else {
|
||||
@ -801,18 +775,6 @@ static int handle_relay_message(relay_server_handle rs, struct message_to_relay
|
||||
sm->m.sm.nd.nbh = NULL;
|
||||
break;
|
||||
}
|
||||
// Signal change to add rtt metric
|
||||
case RMT_CYCLE_RTT_MAP: {
|
||||
rs->server.rtt_ms_mins = ur_map_create();
|
||||
int br = 0;
|
||||
do {
|
||||
br = pthread_barrier_wait(&rtt_barrier);
|
||||
if ((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD)) {
|
||||
perror("rtt barrier wait (message)");
|
||||
}
|
||||
} while ((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
perror("Weird buffer type\n");
|
||||
}
|
||||
@ -1021,8 +983,9 @@ static void setup_listener(void) {
|
||||
#endif
|
||||
);
|
||||
|
||||
if (!turn_params.listener.ioa_eng)
|
||||
if (!turn_params.listener.ioa_eng) {
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
set_ssl_ctx(turn_params.listener.ioa_eng, &turn_params);
|
||||
turn_params.listener.rtcpmap = rtcp_map_create(turn_params.listener.ioa_eng);
|
||||
@ -1093,8 +1056,9 @@ static void setup_barriers(void) {
|
||||
|
||||
#if !defined(TURN_NO_THREAD_BARRIERS)
|
||||
{
|
||||
if (pthread_barrier_init(&barrier, NULL, barrier_count) < 0)
|
||||
if (pthread_barrier_init(&barrier, NULL, barrier_count) < 0) {
|
||||
perror("barrier init");
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -1139,8 +1103,9 @@ static void setup_socket_per_endpoint_udp_listener_servers(void) {
|
||||
int is_5780 = turn_params.rfc5780;
|
||||
|
||||
if (turn_params.general_relay_servers_number <= 1) {
|
||||
while (!(general_relay_servers[0]->ioa_eng))
|
||||
while (!(general_relay_servers[0]->ioa_eng)) {
|
||||
sched_yield();
|
||||
}
|
||||
udp_relay_servers[i] = general_relay_servers[0];
|
||||
continue;
|
||||
} else if (turn_params.general_relay_servers_number > 1) {
|
||||
@ -1241,8 +1206,9 @@ static void setup_socket_per_endpoint_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.udp_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.udp_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
|
||||
|
||||
@ -1285,8 +1251,9 @@ static void setup_socket_per_endpoint_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.dtls_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.dtls_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1298,8 +1265,9 @@ static void setup_socket_per_thread_udp_listener_servers(void) {
|
||||
/* Create listeners */
|
||||
|
||||
for (relayindex = 0; relayindex < get_real_general_relay_servers_number(); relayindex++) {
|
||||
while (!(general_relay_servers[relayindex]->ioa_eng) || !(general_relay_servers[relayindex]->server.e))
|
||||
while (!(general_relay_servers[relayindex]->ioa_eng) || !(general_relay_servers[relayindex]->server.e)) {
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
|
||||
/* Aux UDP servers */
|
||||
@ -1361,8 +1329,9 @@ static void setup_socket_per_thread_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.udp_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.udp_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
|
||||
|
||||
@ -1393,8 +1362,9 @@ static void setup_socket_per_thread_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.dtls_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.dtls_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1450,8 +1420,9 @@ static void setup_socket_per_session_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.udp_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.udp_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
if (!turn_params.no_dtls && (turn_params.no_udp || (turn_params.listener_port != turn_params.tls_listener_port))) {
|
||||
|
||||
@ -1474,8 +1445,9 @@ static void setup_socket_per_session_udp_listener_servers(void) {
|
||||
}
|
||||
} else {
|
||||
turn_params.listener.dtls_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
turn_params.listener.dtls_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1520,54 +1492,58 @@ static void setup_tcp_listener_servers(ioa_engine_handle e, struct relay_server
|
||||
create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i],
|
||||
turn_params.tcp_use_proxy ? turn_params.tcp_proxy_port : turn_params.listener_port,
|
||||
turn_params.verbose, e, send_socket_to_general_relay, relay_server);
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
tcp_services[index + 1] =
|
||||
turn_params.tcp_use_proxy
|
||||
? NULL
|
||||
: create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i],
|
||||
get_alt_listener_port(), turn_params.verbose, e,
|
||||
send_socket_to_general_relay, relay_server);
|
||||
}
|
||||
} else {
|
||||
tcp_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
tcp_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
if (!turn_params.no_tls && !turn_params.tcp_use_proxy &&
|
||||
(turn_params.no_tcp || (turn_params.listener_port != turn_params.tls_listener_port))) {
|
||||
tls_services[index] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i],
|
||||
turn_params.tls_listener_port, turn_params.verbose, e,
|
||||
send_socket_to_general_relay, relay_server);
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
tls_services[index + 1] = create_tls_listener_server(turn_params.listener_ifname, turn_params.listener.addrs[i],
|
||||
get_alt_tls_listener_port(), turn_params.verbose, e,
|
||||
send_socket_to_general_relay, relay_server);
|
||||
}
|
||||
} else {
|
||||
tls_services[index] = NULL;
|
||||
if (turn_params.rfc5780)
|
||||
if (turn_params.rfc5780) {
|
||||
tls_services[index + 1] = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int get_alt_addr(ioa_addr *addr, ioa_addr *alt_addr) {
|
||||
if (!addr || !turn_params.rfc5780 || (turn_params.listener.addrs_number < 2))
|
||||
;
|
||||
else {
|
||||
if (!addr || !turn_params.rfc5780 || (turn_params.listener.addrs_number < 2)) {
|
||||
} else {
|
||||
size_t index = 0xffff;
|
||||
size_t i = 0;
|
||||
int alt_port = -1;
|
||||
int port = addr_get_port(addr);
|
||||
|
||||
if (port == turn_params.listener_port)
|
||||
if (port == turn_params.listener_port) {
|
||||
alt_port = get_alt_listener_port();
|
||||
else if (port == get_alt_listener_port())
|
||||
} else if (port == get_alt_listener_port()) {
|
||||
alt_port = turn_params.listener_port;
|
||||
else if (port == turn_params.tls_listener_port)
|
||||
} else if (port == turn_params.tls_listener_port) {
|
||||
alt_port = get_alt_tls_listener_port();
|
||||
else if (port == get_alt_tls_listener_port())
|
||||
} else if (port == get_alt_tls_listener_port()) {
|
||||
alt_port = turn_params.tls_listener_port;
|
||||
else
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (i = 0; i < turn_params.listener.addrs_number; i++) {
|
||||
if (turn_params.listener.encaddrs && turn_params.listener.encaddrs[i]) {
|
||||
@ -1596,11 +1572,13 @@ static int get_alt_addr(ioa_addr *addr, ioa_addr *alt_addr) {
|
||||
}
|
||||
|
||||
static void run_events(struct event_base *eb, ioa_engine_handle e) {
|
||||
if (!eb && e)
|
||||
if (!eb && e) {
|
||||
eb = e->event_base;
|
||||
}
|
||||
|
||||
if (!eb)
|
||||
if (!eb) {
|
||||
return;
|
||||
}
|
||||
|
||||
struct timeval timeout;
|
||||
|
||||
@ -1626,6 +1604,11 @@ void run_listener_server(struct listener_server *ls) {
|
||||
}
|
||||
}
|
||||
|
||||
if (turn_params.drain_turn_server && global_allocation_count == 0) {
|
||||
turn_params.stop_turn_server = true;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Drain complete, shutting down now...\n");
|
||||
}
|
||||
|
||||
run_events(ls->event_base, ls->ioa_eng);
|
||||
|
||||
rollover_logfile();
|
||||
@ -1669,12 +1652,12 @@ static void setup_relay_server(struct relay_server *rs, ioa_engine_handle e, int
|
||||
bufferevent_enable(rs->auth_in_buf, EV_READ);
|
||||
|
||||
init_turn_server(
|
||||
&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, 0, turn_params.fingerprint,
|
||||
&(rs->server), rs->id, turn_params.verbose, rs->ioa_eng, turn_params.ct, turn_params.fingerprint,
|
||||
DONT_FRAGMENT_SUPPORTED, start_user_check, check_new_allocation_quota, release_allocation_quota,
|
||||
turn_params.external_ip, &turn_params.check_origin, &turn_params.no_tcp_relay, &turn_params.no_udp_relay,
|
||||
&turn_params.stale_nonce, &turn_params.max_allocate_lifetime, &turn_params.channel_lifetime,
|
||||
&turn_params.permission_lifetime, &turn_params.stun_only, &turn_params.no_stun,
|
||||
&turn_params.no_software_attribute, &turn_params.web_admin_listen_on_workers, &turn_params.alternate_servers_list,
|
||||
&turn_params.permission_lifetime, &turn_params.stun_only, &turn_params.no_stun, turn_params.software_attribute,
|
||||
&turn_params.web_admin_listen_on_workers, &turn_params.alternate_servers_list,
|
||||
&turn_params.tls_alternate_servers_list, &turn_params.aux_servers_list, turn_params.udp_self_balance,
|
||||
&turn_params.no_multicast_peers, &turn_params.allow_loopback_peers, &turn_params.ip_whitelist,
|
||||
&turn_params.ip_blacklist, send_socket_to_relay, &turn_params.secure_stun, &turn_params.mobility,
|
||||
@ -1851,8 +1834,9 @@ void setup_server(void) {
|
||||
|
||||
authserver_number = 1 + (authserver_id)(turn_params.cpus / 2);
|
||||
|
||||
if (authserver_number < MIN_AUTHSERVER_NUMBER)
|
||||
if (authserver_number < MIN_AUTHSERVER_NUMBER) {
|
||||
authserver_number = MIN_AUTHSERVER_NUMBER;
|
||||
}
|
||||
|
||||
#if !defined(TURN_NO_THREAD_BARRIERS)
|
||||
|
||||
@ -1869,12 +1853,13 @@ void setup_server(void) {
|
||||
setup_general_relay_servers();
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total General servers: %d\n", (int)get_real_general_relay_servers_number());
|
||||
|
||||
if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD)
|
||||
if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_THREAD) {
|
||||
setup_socket_per_thread_udp_listener_servers();
|
||||
else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT)
|
||||
} else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT) {
|
||||
setup_socket_per_endpoint_udp_listener_servers();
|
||||
else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION)
|
||||
} else if (turn_params.net_engine_version == NEV_UDP_SOCKET_PER_SESSION) {
|
||||
setup_socket_per_session_udp_listener_servers();
|
||||
}
|
||||
|
||||
if (turn_params.net_engine_version != NEV_UDP_SOCKET_PER_THREAD) {
|
||||
setup_tcp_listener_servers(turn_params.listener.ioa_eng, NULL);
|
||||
@ -1918,62 +1903,18 @@ void setup_server(void) {
|
||||
|
||||
void init_listener(void) { memset(&turn_params.listener, 0, sizeof(struct listener_server)); }
|
||||
|
||||
///////////////////////////////
|
||||
|
||||
// Signal change to add rtt metrics
|
||||
size_t cycle_rtt_ms_maps(ur_map **rtt_ms_maps, size_t len) {
|
||||
if (len != 1 + ((turnserver_id)-1)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "cycle_rtt_ms_maps, length is %ld, must be %ld\n", len,
|
||||
1L + ((turnserver_id)-1));
|
||||
return 0;
|
||||
}
|
||||
size_t count = 0;
|
||||
void enable_drain_mode(void) {
|
||||
// Tell each turn_server we are draining
|
||||
for (size_t i = 0; i < get_real_general_relay_servers_number(); i++) {
|
||||
if (general_relay_servers[i] && general_relay_servers[i]->server.rtt_ms_mins) {
|
||||
rtt_ms_maps[count] = general_relay_servers[i]->server.rtt_ms_mins;
|
||||
++count;
|
||||
if (general_relay_servers[i]) {
|
||||
general_relay_servers[i]->server.is_draining = true;
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < get_real_udp_relay_servers_number(); i++) {
|
||||
if (udp_relay_servers[i] && udp_relay_servers[i]->server.rtt_ms_mins) {
|
||||
rtt_ms_maps[count] = udp_relay_servers[i]->server.rtt_ms_mins;
|
||||
++count;
|
||||
if (udp_relay_servers[i]) {
|
||||
udp_relay_servers[i]->server.is_draining = true;
|
||||
}
|
||||
}
|
||||
|
||||
static size_t last_count = 0;
|
||||
if (last_count != count) {
|
||||
if (last_count) {
|
||||
if (pthread_barrier_destroy(&rtt_barrier) != 0) {
|
||||
perror("rtt barrier destroy");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (pthread_barrier_init(&rtt_barrier, NULL, count + 1) != 0) {
|
||||
perror("rtt barrier init");
|
||||
return 0;
|
||||
}
|
||||
last_count = count;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < get_real_general_relay_servers_number(); i++) {
|
||||
if (general_relay_servers[i] && general_relay_servers[i]->server.rtt_ms_mins) {
|
||||
send_cycle_rtt_map_to_relay(i);
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; i < get_real_udp_relay_servers_number(); i++) {
|
||||
if (udp_relay_servers[i] && udp_relay_servers[i]->server.rtt_ms_mins) {
|
||||
send_cycle_rtt_map_to_relay(i + TURNSERVER_ID_BOUNDARY_BETWEEN_TCP_AND_UDP);
|
||||
}
|
||||
}
|
||||
|
||||
int br = 0;
|
||||
do {
|
||||
br = pthread_barrier_wait(&rtt_barrier);
|
||||
if ((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD)) {
|
||||
perror("rtt barrier wait");
|
||||
}
|
||||
} while ((br < 0) && (br != PTHREAD_BARRIER_SERIAL_THREAD));
|
||||
|
||||
return count;
|
||||
turn_params.drain_turn_server = true;
|
||||
}
|
||||
///////////////////////////////
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -35,15 +35,10 @@
|
||||
#ifndef __IOA_LIBIMPL__
|
||||
#define __IOA_LIBIMPL__
|
||||
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include <event2/thread.h>
|
||||
#include "ns_turn_ioalib.h" // IWYU pragma: export
|
||||
|
||||
#include "ns_turn_openssl.h"
|
||||
|
||||
#include "ns_turn_ioalib.h"
|
||||
#include "ns_turn_maps.h"
|
||||
#include "ns_turn_maps_rtcp.h"
|
||||
#include "ns_turn_server.h"
|
||||
@ -55,6 +50,12 @@
|
||||
|
||||
#include "ns_sm.h"
|
||||
|
||||
#include <event2/buffer.h>
|
||||
#include <event2/bufferevent.h>
|
||||
#include <event2/event.h>
|
||||
|
||||
#include <event2/thread.h>
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -288,10 +289,6 @@ void *allocate_super_memory_engine_func(ioa_engine_handle e, size_t size, const
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
// Signal change to add rtt metrics
|
||||
int send_cycle_rtt_map_to_relay(turnserver_id id);
|
||||
size_t cycle_rtt_ms_maps(ur_map **rtt_ms_maps, size_t len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -33,15 +33,43 @@ prom_counter_t *turn_total_traffic_peer_rcvb;
|
||||
prom_counter_t *turn_total_traffic_peer_sentp;
|
||||
prom_counter_t *turn_total_traffic_peer_sentb;
|
||||
|
||||
prom_counter_t *turn_total_sessions;
|
||||
|
||||
prom_gauge_t *turn_total_allocations;
|
||||
|
||||
// Signal change to add metrics
|
||||
prom_counter_t *turn_rtt_client[8];
|
||||
prom_counter_t *turn_rtt_peer[8];
|
||||
prom_counter_t *turn_rtt_combined[8];
|
||||
prom_counter_t *turn_with_no_ping_rcvp;
|
||||
#if MHD_VERSION >= 0x00097002
|
||||
#define MHD_RESULT enum MHD_Result
|
||||
#else
|
||||
#define MHD_RESULT int
|
||||
#endif
|
||||
|
||||
MHD_RESULT promhttp_handler(void *cls, struct MHD_Connection *connection, const char *url, const char *method,
|
||||
const char *version, const char *upload_data, size_t *upload_data_size, void **con_cls) {
|
||||
MHD_RESULT ret;
|
||||
|
||||
char *body = "not found";
|
||||
enum MHD_ResponseMemoryMode mode = MHD_RESPMEM_PERSISTENT;
|
||||
unsigned int status = MHD_HTTP_NOT_FOUND;
|
||||
|
||||
if (strcmp(method, "GET") != 0) {
|
||||
status = MHD_HTTP_METHOD_NOT_ALLOWED;
|
||||
body = "method not allowed";
|
||||
} else if (strcmp(url, turn_params.prometheus_path) == 0) {
|
||||
body = prom_collector_registry_bridge(PROM_COLLECTOR_REGISTRY_DEFAULT);
|
||||
mode = MHD_RESPMEM_MUST_FREE;
|
||||
status = MHD_HTTP_OK;
|
||||
}
|
||||
|
||||
struct MHD_Response *response = MHD_create_response_from_buffer(strlen(body), body, mode);
|
||||
if (response == NULL) {
|
||||
if (mode == MHD_RESPMEM_MUST_FREE) {
|
||||
free(body);
|
||||
}
|
||||
ret = MHD_NO;
|
||||
} else {
|
||||
ret = MHD_queue_response(connection, status, response);
|
||||
MHD_destroy_response(response);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void start_prometheus_server(void) {
|
||||
if (turn_params.prometheus == 0) {
|
||||
@ -106,81 +134,13 @@ void start_prometheus_server(void) {
|
||||
turn_total_traffic_peer_sentb = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_total_traffic_peer_sentb", "Represents total finished sessions peer sent bytes", 0, NULL));
|
||||
|
||||
// Create total completed session counter metric
|
||||
const char *total_sessions_labels[] = {"duration", "sent_rate"};
|
||||
turn_total_sessions = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_total_sessions", "Represents total completed sessions", 2, total_sessions_labels));
|
||||
|
||||
// Create total allocations number gauge metric
|
||||
const char *total_allocations_labels[] = {"type", "client_addr_family"};
|
||||
const char *typeLabel[] = {"type"};
|
||||
turn_total_allocations = prom_collector_registry_must_register_metric(
|
||||
prom_gauge_new("turn_total_allocations", "Represents current allocations number", 2, total_allocations_labels));
|
||||
|
||||
// Signal change to add metrics
|
||||
// Create round trip time pseudo-histogram metrics
|
||||
// values must be kept in sync with observation function below
|
||||
|
||||
turn_rtt_client[0] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_25ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[1] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_50ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[2] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_100ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[3] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_200ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[4] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_400ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[5] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_800ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[6] = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_rtt_client_le_1500ms", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
turn_rtt_client[7] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_client_more", "Represents measured round trip time of client with channel", 0, NULL));
|
||||
|
||||
turn_rtt_peer[0] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_25ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[1] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_50ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[2] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_100ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[3] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_200ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[4] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_400ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[5] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_800ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[6] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_le_1500ms", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
turn_rtt_peer[7] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_peer_more", "Represents measured round trip time of peer with channel", 0, NULL));
|
||||
|
||||
turn_rtt_combined[0] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_25ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[1] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_50ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[2] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_100ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[3] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_200ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[4] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_400ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[5] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_800ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[6] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_le_1500ms", "Represents combined round trip time of channel", 0, NULL));
|
||||
turn_rtt_combined[7] = prom_collector_registry_must_register_metric(
|
||||
prom_counter_new("turn_rtt_combined_more", "Represents combined round trip time of channel", 0, NULL));
|
||||
|
||||
turn_with_no_ping_rcvp = prom_collector_registry_must_register_metric(prom_counter_new(
|
||||
"turn_with_no_ping_rcvp", "Count of packets received for TURN where no ICE ping has been observed", 0, NULL));
|
||||
|
||||
promhttp_set_active_collector_registry(NULL);
|
||||
prom_gauge_new("turn_total_allocations", "Represents current allocations number", 1, typeLabel));
|
||||
|
||||
// some flags appeared first in microhttpd v0.9.53
|
||||
unsigned int flags = 0;
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_IPv6) && is_ipv6_enabled()) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
}
|
||||
#if MHD_VERSION >= 0x00095300
|
||||
flags |= MHD_USE_ERROR_LOG;
|
||||
#endif
|
||||
@ -198,7 +158,36 @@ void start_prometheus_server(void) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "prometheus exporter server will start using SELECT. "
|
||||
"The exporter might be unreachable on highly used servers\n");
|
||||
}
|
||||
struct MHD_Daemon *daemon = promhttp_start_daemon(flags, turn_params.prometheus_port, NULL, NULL);
|
||||
|
||||
ioa_addr server_addr;
|
||||
addr_set_any(&server_addr);
|
||||
if (turn_params.prometheus_address[0]) {
|
||||
if (make_ioa_addr((const uint8_t *)turn_params.prometheus_address, turn_params.prometheus_port, &server_addr) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "could not parse prometheus collector's server address\n");
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_ipv6_enabled() && server_addr.ss.sa_family == AF_INET6) {
|
||||
flags |= MHD_USE_IPv6;
|
||||
}
|
||||
} else {
|
||||
if (MHD_is_feature_supported(MHD_FEATURE_IPv6) && is_ipv6_enabled()) {
|
||||
flags |= MHD_USE_DUAL_STACK;
|
||||
server_addr.ss.sa_family = AF_INET6;
|
||||
server_addr.s6.sin6_port = htons((uint16_t)turn_params.prometheus_port);
|
||||
} else {
|
||||
server_addr.ss.sa_family = AF_INET;
|
||||
server_addr.s4.sin_port = htons((uint16_t)turn_params.prometheus_port);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t addr[MAX_IOA_ADDR_STRING];
|
||||
addr_to_string(&server_addr, addr);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "prometheus exporter server will listen on %s\n", addr);
|
||||
|
||||
struct MHD_Daemon *daemon =
|
||||
MHD_start_daemon(flags, 0, NULL, NULL, &promhttp_handler, NULL, MHD_OPTION_LISTENING_ADDRESS_REUSE, 1,
|
||||
MHD_OPTION_SOCK_ADDR, &server_addr, MHD_OPTION_END);
|
||||
if (daemon == NULL) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "could not start prometheus collector\n");
|
||||
return;
|
||||
@ -209,9 +198,8 @@ void start_prometheus_server(void) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Signal change to add metrics
|
||||
void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb,
|
||||
unsigned long sentp, unsigned long sentb, unsigned long without_pingp, bool peer) {
|
||||
unsigned long sentp, unsigned long sentb, bool peer) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
|
||||
const char *label[] = {realm, NULL};
|
||||
@ -240,26 +228,20 @@ void prom_set_finished_traffic(const char *realm, const char *user, unsigned lon
|
||||
prom_counter_add(turn_total_traffic_sentp, sentp, NULL);
|
||||
prom_counter_add(turn_total_traffic_sentb, sentb, NULL);
|
||||
}
|
||||
// Signal change to add metrics
|
||||
if (without_pingp) {
|
||||
prom_counter_add(turn_with_no_ping_rcvp, without_pingp, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void prom_inc_allocation(SOCKET_TYPE type, int addr_family) {
|
||||
void prom_inc_allocation(SOCKET_TYPE type) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
const char *labels[] = {socket_type_name(type), addr_family_name(addr_family)};
|
||||
prom_gauge_inc(turn_total_allocations, labels);
|
||||
const char *label[] = {socket_type_name(type)};
|
||||
prom_gauge_inc(turn_total_allocations, label);
|
||||
}
|
||||
}
|
||||
|
||||
void prom_dec_allocation(SOCKET_TYPE type, int addr_family, unsigned long duration, unsigned long sent_rate_kbps) {
|
||||
void prom_dec_allocation(SOCKET_TYPE type) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
const char *labels[] = {socket_type_name(type), addr_family_name(addr_family)};
|
||||
prom_gauge_dec(turn_total_allocations, labels);
|
||||
const char *total_sessions_labels[] = {duration_name(duration), rate_name(sent_rate_kbps)};
|
||||
prom_counter_add(turn_total_sessions, 1, total_sessions_labels);
|
||||
const char *label[] = {socket_type_name(type)};
|
||||
prom_gauge_dec(turn_total_allocations, label);
|
||||
}
|
||||
}
|
||||
|
||||
@ -297,50 +279,6 @@ int is_ipv6_enabled(void) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
// Signal change to add metrics
|
||||
void prom_observe_rtt(prom_counter_t *counter[8], int microseconds) {
|
||||
if (microseconds <= 25000) {
|
||||
prom_counter_add(counter[0], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 50000) {
|
||||
prom_counter_add(counter[1], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 100000) {
|
||||
prom_counter_add(counter[2], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 200000) {
|
||||
prom_counter_add(counter[3], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 400000) {
|
||||
prom_counter_add(counter[4], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 800000) {
|
||||
prom_counter_add(counter[5], 1, NULL);
|
||||
}
|
||||
if (microseconds <= 1500000) {
|
||||
prom_counter_add(counter[6], 1, NULL);
|
||||
}
|
||||
prom_counter_add(counter[7], 1, NULL);
|
||||
}
|
||||
|
||||
void prom_observe_rtt_client(int microseconds) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
prom_observe_rtt(turn_rtt_client, microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void prom_observe_rtt_peer(int microseconds) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
prom_observe_rtt(turn_rtt_peer, microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
void prom_observe_rtt_combined(int microseconds) {
|
||||
if (turn_params.prometheus == 1) {
|
||||
prom_observe_rtt(turn_rtt_combined, microseconds);
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
void start_prometheus_server(void) {
|
||||
@ -349,14 +287,13 @@ void start_prometheus_server(void) {
|
||||
}
|
||||
|
||||
void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb,
|
||||
unsigned long sentp, unsigned long sentb, unsigned long without_pingp, bool peer) {
|
||||
unsigned long sentp, unsigned long sentb, bool peer) {
|
||||
UNUSED_ARG(realm);
|
||||
UNUSED_ARG(user);
|
||||
UNUSED_ARG(rsvp);
|
||||
UNUSED_ARG(rsvb);
|
||||
UNUSED_ARG(sentp);
|
||||
UNUSED_ARG(sentb);
|
||||
UNUSED_ARG(without_pingp);
|
||||
UNUSED_ARG(peer);
|
||||
}
|
||||
|
||||
|
||||
@ -18,7 +18,6 @@ extern "C" {
|
||||
#endif
|
||||
#include <microhttpd.h>
|
||||
#include <prom.h>
|
||||
#include <promhttp.h>
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif /* __clplusplus */
|
||||
@ -53,26 +52,17 @@ extern prom_counter_t *turn_total_traffic_peer_sentb;
|
||||
|
||||
extern prom_gauge_t *turn_total_allocations_number;
|
||||
|
||||
// Signal change to add metrics
|
||||
extern prom_counter_t *turn_rtt_client[8];
|
||||
extern prom_counter_t *turn_rtt_peer[8];
|
||||
extern prom_counter_t *turn_rtt_combined[8];
|
||||
extern prom_counter_t *turn_with_no_ping_rcvp;
|
||||
|
||||
#define TURN_ALLOC_STR_MAX_SIZE (20)
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
void start_prometheus_server(void);
|
||||
|
||||
// Signal change to add metrics
|
||||
void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb,
|
||||
unsigned long sentp, unsigned long sentb, unsigned long without_pingp, bool peer);
|
||||
unsigned long sentp, unsigned long sentb, bool peer);
|
||||
|
||||
void prom_inc_allocation(SOCKET_TYPE type, int addr_family);
|
||||
void prom_dec_allocation(SOCKET_TYPE type, int addr_family, unsigned long duration, unsigned long sent_rate_kbps);
|
||||
void prom_inc_allocation(SOCKET_TYPE type);
|
||||
void prom_dec_allocation(SOCKET_TYPE type);
|
||||
|
||||
int is_ipv6_enabled(void);
|
||||
|
||||
@ -80,19 +70,12 @@ void prom_inc_stun_binding_request(void);
|
||||
void prom_inc_stun_binding_response(void);
|
||||
void prom_inc_stun_binding_error(void);
|
||||
|
||||
// Signal change to add metrics
|
||||
void prom_observe_rtt(prom_counter_t *counter[8], int microseconds);
|
||||
void prom_observe_rtt_client(int microseconds);
|
||||
void prom_observe_rtt_peer(int microseconds);
|
||||
void prom_observe_rtt_combined(int microseconds);
|
||||
|
||||
#else
|
||||
|
||||
void start_prometheus_server(void);
|
||||
|
||||
// Signal change to add metrics
|
||||
void prom_set_finished_traffic(const char *realm, const char *user, unsigned long rsvp, unsigned long rsvb,
|
||||
unsigned long sentp, unsigned long sentb, unsigned long without_pingp, bool peer);
|
||||
unsigned long sentp, unsigned long sentb, bool peer);
|
||||
|
||||
void prom_inc_allocation(SOCKET_TYPE type);
|
||||
void prom_dec_allocation(SOCKET_TYPE type);
|
||||
|
||||
@ -85,12 +85,13 @@ static void server_input_handler(struct evconnlistener *l, evutil_socket_t fd, s
|
||||
|
||||
SOCKET_TYPE st = TENTATIVE_TCP_SOCKET;
|
||||
|
||||
if (turn_params.tcp_use_proxy)
|
||||
if (turn_params.tcp_use_proxy) {
|
||||
st = TCP_SOCKET_PROXY;
|
||||
else if (turn_params.no_tls)
|
||||
} else if (turn_params.no_tls) {
|
||||
st = TCP_SOCKET;
|
||||
else if (turn_params.no_tcp)
|
||||
} else if (turn_params.no_tcp) {
|
||||
st = TLS_SOCKET;
|
||||
}
|
||||
|
||||
ioa_socket_handle ioas = create_ioa_socket_from_fd(server->e, fd, NULL, st, CLIENT_SOCKET,
|
||||
&(server->sm.m.sm.nd.src_addr), &(server->addr));
|
||||
@ -143,10 +144,11 @@ static void sctp_server_input_handler(struct evconnlistener *l, evutil_socket_t
|
||||
|
||||
SOCKET_TYPE st = TENTATIVE_SCTP_SOCKET;
|
||||
|
||||
if (turn_params.no_tls)
|
||||
if (turn_params.no_tls) {
|
||||
st = SCTP_SOCKET;
|
||||
else if (turn_params.no_tcp)
|
||||
} else if (turn_params.no_tcp) {
|
||||
st = TLS_SCTP_SOCKET;
|
||||
}
|
||||
|
||||
ioa_socket_handle ioas = create_ioa_socket_from_fd(server->e, fd, NULL, st, CLIENT_SOCKET,
|
||||
&(server->sm.m.sm.nd.src_addr), &(server->addr));
|
||||
@ -181,8 +183,9 @@ static int create_server_listener(tls_listener_relay_server_type *server) {
|
||||
|
||||
FUNCSTART;
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
evutil_socket_t tls_listen_fd = -1;
|
||||
|
||||
@ -230,12 +233,13 @@ static int create_server_listener(tls_listener_relay_server_type *server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!turn_params.no_tcp && !turn_params.no_tls)
|
||||
if (!turn_params.no_tcp && !turn_params.no_tls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "TLS/TCP listener opened on ");
|
||||
else if (!turn_params.no_tls)
|
||||
} else if (!turn_params.no_tls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "TLS listener opened on ");
|
||||
else if (!turn_params.no_tcp)
|
||||
} else if (!turn_params.no_tcp) {
|
||||
addr_debug_print(server->verbose, &server->addr, "TCP listener opened on ");
|
||||
}
|
||||
|
||||
FUNCEND;
|
||||
|
||||
@ -248,8 +252,9 @@ static int sctp_create_server_listener(tls_listener_relay_server_type *server) {
|
||||
|
||||
FUNCSTART;
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
evutil_socket_t tls_listen_fd = -1;
|
||||
|
||||
@ -280,10 +285,11 @@ static int sctp_create_server_listener(tls_listener_relay_server_type *server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!turn_params.no_tls)
|
||||
if (!turn_params.no_tls) {
|
||||
addr_debug_print(server->verbose, &server->addr, "TLS/SCTP listener opened on ");
|
||||
else
|
||||
} else {
|
||||
addr_debug_print(server->verbose, &server->addr, "SCTP listener opened on ");
|
||||
}
|
||||
|
||||
FUNCEND;
|
||||
|
||||
@ -296,14 +302,16 @@ static int init_server(tls_listener_relay_server_type *server, const char *ifnam
|
||||
int verbose, ioa_engine_handle e, ioa_engine_new_connection_event_handler send_socket,
|
||||
struct relay_server *relay_server) {
|
||||
|
||||
if (!server)
|
||||
if (!server) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
server->connect_cb = send_socket;
|
||||
server->relay_server = relay_server;
|
||||
|
||||
if (ifname)
|
||||
if (ifname) {
|
||||
STRCPY(server->ifname, ifname);
|
||||
}
|
||||
|
||||
if (make_ioa_addr((const uint8_t *)local_address, port, &server->addr) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot create a TCP/TLS listener for address: %s\n", local_address);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -73,8 +73,6 @@ struct admin_server {
|
||||
struct bufferevent *https_out_buf;
|
||||
ur_map *sessions;
|
||||
pthread_t thr;
|
||||
// Signal change to add rtt metrics
|
||||
ioa_timer_handle rtt_ev;
|
||||
};
|
||||
|
||||
///////////////////////////////////////////
|
||||
@ -115,10 +113,6 @@ void https_admin_server_receive_message(struct bufferevent *bev, void *ptr);
|
||||
int send_turn_session_info(struct turn_session_info *tsi);
|
||||
void send_https_socket(ioa_socket_handle s);
|
||||
|
||||
// Signal change to add rtt metrics
|
||||
int rtt_foreach(ur_map_key_type, ur_map_value_type);
|
||||
void admin_server_rtt_timer_handler(ioa_engine *, void *);
|
||||
|
||||
////////////////////////////////////////////
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -137,8 +137,9 @@ static void turnports_init(turnports *tp, uint16_t start, uint16_t end) {
|
||||
|
||||
turnports *turnports_create(super_memory_t *sm, uint16_t start, uint16_t end) {
|
||||
|
||||
if (start > end)
|
||||
if (start > end) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
turnports *ret = (turnports *)allocate_super_memory_region(sm, sizeof(turnports));
|
||||
turnports_init(ret, start, end);
|
||||
@ -147,9 +148,9 @@ turnports *turnports_create(super_memory_t *sm, uint16_t start, uint16_t end) {
|
||||
}
|
||||
|
||||
uint16_t turnports_size(turnports *tp) {
|
||||
if (!tp)
|
||||
if (!tp) {
|
||||
return 0;
|
||||
else {
|
||||
} else {
|
||||
TURN_MUTEX_LOCK(&tp->mutex);
|
||||
uint16_t ret = (uint16_t)((tp->high - tp->low));
|
||||
TURN_MUTEX_UNLOCK(&tp->mutex);
|
||||
@ -254,9 +255,9 @@ int turnports_allocate_even(turnports *tp, int allocate_rtcp, uint64_t *reservat
|
||||
}
|
||||
|
||||
int turnports_is_allocated(turnports *tp, uint16_t port) {
|
||||
if (!tp)
|
||||
if (!tp) {
|
||||
return 0;
|
||||
else {
|
||||
} else {
|
||||
TURN_MUTEX_LOCK(&tp->mutex);
|
||||
int ret = is_taken(tp->status[port]);
|
||||
TURN_MUTEX_UNLOCK(&tp->mutex);
|
||||
@ -294,8 +295,9 @@ struct _turnipports {
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
static ur_addr_map *get_map(turnipports *tp, uint8_t transport) {
|
||||
if (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE)
|
||||
if (transport == STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE) {
|
||||
return &(tp->ip_to_turnports_tcp);
|
||||
}
|
||||
return &(tp->ip_to_turnports_udp);
|
||||
}
|
||||
//////////////////////////////////////////////////
|
||||
|
||||
@ -68,6 +68,13 @@ static TURN_MUTEX_DECLARE(o_to_realm_mutex);
|
||||
static ur_string_map *o_to_realm = NULL;
|
||||
static secrets_list_t realms_list;
|
||||
|
||||
#ifndef _MSC_VER
|
||||
_Atomic
|
||||
#else
|
||||
volatile
|
||||
#endif
|
||||
size_t global_allocation_count = 0; // used for drain mode, to know when all allocations have gone away
|
||||
|
||||
static char userdb_type_unknown[] = "Unknown";
|
||||
static char userdb_type_sqlite[] = "SQLite";
|
||||
static char userdb_type_postgresql[] = "PostgreSQL";
|
||||
@ -399,8 +406,9 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
ioa_network_buffer_handle nbh) {
|
||||
int ret = -1;
|
||||
|
||||
if (max_session_time)
|
||||
if (max_session_time) {
|
||||
*max_session_time = 0;
|
||||
}
|
||||
|
||||
if (in_oauth && out_oauth && usname && usname[0]) {
|
||||
|
||||
@ -423,11 +431,13 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
memset(&rawKey, 0, sizeof(rawKey));
|
||||
|
||||
int gres = (*(dbd->get_oauth_key))(usname, &rawKey);
|
||||
if (gres < 0)
|
||||
if (gres < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!rawKey.kid[0])
|
||||
if (!rawKey.kid[0]) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (rawKey.lifetime) {
|
||||
if (!turn_time_before(turn_time(), (turn_time_t)(rawKey.timestamp + rawKey.lifetime + OAUTH_TIME_DELTA))) {
|
||||
@ -446,7 +456,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
oauth_key okey;
|
||||
memset(&okey, 0, sizeof(okey));
|
||||
|
||||
if (convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd, &okey, err_msg, err_msg_size)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s\n", err_msg);
|
||||
return -1;
|
||||
}
|
||||
@ -473,7 +483,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
}
|
||||
}
|
||||
|
||||
if (decode_oauth_token((const uint8_t *)server_name, &etoken, &okey, &dot) < 0) {
|
||||
if (!decode_oauth_token((const uint8_t *)server_name, &etoken, &okey, &dot)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot decode oauth token\n");
|
||||
return -1;
|
||||
}
|
||||
@ -535,8 +545,9 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
|
||||
init_secrets_list(&sl);
|
||||
|
||||
if (get_auth_secrets(&sl, realm) < 0)
|
||||
if (get_auth_secrets(&sl, realm) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
ts = get_rest_api_timestamp((char *)usname);
|
||||
|
||||
@ -550,8 +561,9 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
|
||||
stun_attr_ref sar = stun_attr_get_first_by_type_str(
|
||||
ioa_network_buffer_data(nbh), ioa_network_buffer_get_size(nbh), STUN_ATTRIBUTE_MESSAGE_INTEGRITY);
|
||||
if (!sar)
|
||||
if (!sar) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int sarlen = stun_attr_get_len(sar);
|
||||
switch (sarlen) {
|
||||
@ -571,7 +583,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
|
||||
if (secret) {
|
||||
if (stun_calculate_hmac(usname, strlen((char *)usname), (const uint8_t *)secret, strlen(secret), hmac,
|
||||
&hmac_len, SHATYPE_DEFAULT) >= 0) {
|
||||
&hmac_len, SHATYPE_DEFAULT)) {
|
||||
size_t pwd_length = 0;
|
||||
char *pwd = base64_encode(hmac, hmac_len, &pwd_length);
|
||||
|
||||
@ -579,9 +591,7 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
if (pwd_length < 1) {
|
||||
free(pwd);
|
||||
} else {
|
||||
if (stun_produce_integrity_key_str((uint8_t *)usname, realm, (uint8_t *)pwd, key, SHATYPE_DEFAULT) >=
|
||||
0) {
|
||||
|
||||
if (stun_produce_integrity_key_str((uint8_t *)usname, realm, (uint8_t *)pwd, key, SHATYPE_DEFAULT)) {
|
||||
if (stun_check_message_integrity_by_key_str(TURN_CREDENTIALS_LONG_TERM, ioa_network_buffer_data(nbh),
|
||||
ioa_network_buffer_get_size(nbh), key, pwdtmp,
|
||||
SHATYPE_DEFAULT) > 0) {
|
||||
@ -591,8 +601,9 @@ int get_user_key(int in_oauth, int *out_oauth, int *max_session_time, uint8_t *u
|
||||
}
|
||||
free(pwd);
|
||||
|
||||
if (ret == 0)
|
||||
if (ret == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -679,6 +690,15 @@ int check_new_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) {
|
||||
free(username);
|
||||
ur_string_map_unlock(rp->status.alloc_counters);
|
||||
}
|
||||
|
||||
#ifndef _MSC_VER
|
||||
global_allocation_count++;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "Global turn allocation count incremented, now %ld\n", global_allocation_count);
|
||||
#else
|
||||
size_t cur_count = (size_t)InterlockedIncrement((volatile LONG *)&global_allocation_count);
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_DEBUG, "Global turn allocation count incremented, now %ld\n", cur_count);
|
||||
#endif
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -699,63 +719,97 @@ void release_allocation_quota(uint8_t *user, int oauth, uint8_t *realm) {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (rp->status.total_current_allocs)
|
||||
if (rp->status.total_current_allocs) {
|
||||
--(rp->status.total_current_allocs);
|
||||
}
|
||||
ur_string_map_unlock(rp->status.alloc_counters);
|
||||
free(username);
|
||||
}
|
||||
|
||||
int log_level = TURN_LOG_LEVEL_DEBUG;
|
||||
if (turn_params.drain_turn_server) {
|
||||
log_level = TURN_LOG_LEVEL_INFO;
|
||||
}
|
||||
#ifndef _MSC_VER
|
||||
global_allocation_count--;
|
||||
TURN_LOG_FUNC(log_level, "Global turn allocation count decremented, now %ld\n", global_allocation_count);
|
||||
#else
|
||||
size_t cur_count = (size_t)InterlockedDecrement((volatile LONG *)&global_allocation_count);
|
||||
TURN_LOG_FUNC(log_level, "Global turn allocation count decremented, now %ld\n", cur_count);
|
||||
#endif
|
||||
}
|
||||
|
||||
//////////////////////////////////
|
||||
|
||||
int add_static_user_account(char *user) {
|
||||
/* Realm is either default or empty for users taken from file or command-line */
|
||||
if (user && !turn_params.use_auth_secret_with_timestamp) {
|
||||
char *s = strstr(user, ":");
|
||||
if (!s || (s == user) || (strlen(s) < 2)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user account: %s\n", user);
|
||||
} else {
|
||||
size_t ulen = s - user;
|
||||
char *usname = (char *)calloc(ulen + 1, sizeof(char));
|
||||
strncpy(usname, user, ulen);
|
||||
usname[ulen] = 0;
|
||||
if (SASLprep((uint8_t *)usname) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n", user);
|
||||
free(usname);
|
||||
return -1;
|
||||
}
|
||||
s = skip_blanks(s + 1);
|
||||
hmackey_t *key = (hmackey_t *)malloc(sizeof(hmackey_t));
|
||||
if (strstr(s, "0x") == s) {
|
||||
char *keysource = s + 2;
|
||||
size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
|
||||
if (strlen(keysource) < sz * 2) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s\n", s);
|
||||
}
|
||||
if (convert_string_key_to_binary(keysource, *key, sz) < 0) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s\n", s);
|
||||
free(usname);
|
||||
free(key);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
// this is only for default realm
|
||||
stun_produce_integrity_key_str((uint8_t *)usname, (uint8_t *)get_realm(NULL)->options.name, (uint8_t *)s, *key,
|
||||
SHATYPE_DEFAULT);
|
||||
}
|
||||
{
|
||||
ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts);
|
||||
ur_string_map_put(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname,
|
||||
(ur_string_map_value_type)*key);
|
||||
ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts);
|
||||
}
|
||||
turn_params.default_users_db.ram_db.users_number++;
|
||||
free(usname);
|
||||
return 0;
|
||||
}
|
||||
if (!user || turn_params.use_auth_secret_with_timestamp) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return -1;
|
||||
char *s = strstr(user, ":");
|
||||
if (!s || (s == user) || (strlen(s) < 2)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user account: %s\n", user);
|
||||
return -1;
|
||||
}
|
||||
|
||||
size_t ulen = s - user;
|
||||
|
||||
// TODO: TURN usernames should be length limited by the RFC.
|
||||
// are user account names as well? If so, we can avoid allocating
|
||||
// and instead use a stack buffer.
|
||||
char *usname = (char *)malloc(ulen + 1);
|
||||
if (!usname) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
strncpy(usname, user, ulen);
|
||||
usname[ulen] = 0;
|
||||
|
||||
if (!SASLprep((uint8_t *)usname)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n", user);
|
||||
free(usname);
|
||||
return -1;
|
||||
}
|
||||
s = skip_blanks(s + 1);
|
||||
|
||||
hmackey_t *key = (hmackey_t *)malloc(sizeof(hmackey_t));
|
||||
if (!key) {
|
||||
free(usname);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (strstr(s, "0x") == s) {
|
||||
char *keysource = s + 2;
|
||||
size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
|
||||
if (strlen(keysource) < sz * 2) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: %s\n", s);
|
||||
}
|
||||
convert_string_key_to_binary(keysource, *key, sz);
|
||||
} else {
|
||||
// this is only for default realm
|
||||
stun_produce_integrity_key_str((uint8_t *)usname, (uint8_t *)get_realm(NULL)->options.name, (uint8_t *)s, *key,
|
||||
SHATYPE_DEFAULT);
|
||||
}
|
||||
|
||||
// the ur_string_map functions only fail (well... other than allocation failures, which aren't handled)
|
||||
// if the map isn't valid. So we only need to check the result of locking.
|
||||
if (!ur_string_map_lock(turn_params.default_users_db.ram_db.static_accounts)) {
|
||||
free(usname);
|
||||
free(key);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// key argument (the usname variable) is deep-copied, so ownership isn't transfered, and we still need to free usname
|
||||
// later.. value argument (the key variable) has ownership transfered into this function
|
||||
ur_string_map_put(turn_params.default_users_db.ram_db.static_accounts, (ur_string_map_key_type)usname,
|
||||
(ur_string_map_value_type)*key);
|
||||
ur_string_map_unlock(turn_params.default_users_db.ram_db.static_accounts);
|
||||
|
||||
turn_params.default_users_db.ram_db.users_number++;
|
||||
|
||||
free(usname);
|
||||
return 0;
|
||||
}
|
||||
|
||||
////////////////// Admin /////////////////////////
|
||||
@ -800,8 +854,9 @@ static int del_secret(uint8_t *secret, uint8_t *realm) {
|
||||
|
||||
static int set_secret(uint8_t *secret, uint8_t *realm) {
|
||||
|
||||
if (!secret || (secret[0] == 0))
|
||||
if (!secret || (secret[0] == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
must_set_admin_realm(realm);
|
||||
|
||||
@ -851,8 +906,9 @@ static int list_origins(uint8_t *realm) {
|
||||
}
|
||||
|
||||
static int set_realm_option_one(uint8_t *realm, unsigned long value, const char *opt) {
|
||||
if (value == (unsigned long)-1)
|
||||
if (value == (unsigned long)-1) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const turn_dbdriver_t *dbd = get_dbdriver();
|
||||
if (dbd && dbd->set_realm_option_one) {
|
||||
@ -935,11 +991,10 @@ int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint
|
||||
|
||||
{
|
||||
stun_produce_integrity_key_str(user, realm, pwd, key, SHATYPE_DEFAULT);
|
||||
size_t i = 0;
|
||||
size_t sz = get_hmackey_size(SHATYPE_DEFAULT);
|
||||
int maxsz = (int)(sz * 2) + 1;
|
||||
char *s = skey;
|
||||
for (i = 0; (i < sz) && (maxsz > 2); i++) {
|
||||
for (size_t i = 0; (i < sz) && (maxsz > 2); i++) {
|
||||
snprintf(s, (size_t)(sz * 2), "%02x", (unsigned int)key[i]);
|
||||
maxsz -= 2;
|
||||
s += 2;
|
||||
@ -956,16 +1011,19 @@ int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint
|
||||
|
||||
} else if (dbd) {
|
||||
|
||||
if (!is_admin)
|
||||
if (!is_admin) {
|
||||
must_set_admin_realm(realm);
|
||||
}
|
||||
|
||||
if (ct == TA_DELETE_USER) {
|
||||
if (is_admin) {
|
||||
if (dbd->del_admin_user)
|
||||
if (dbd->del_admin_user) {
|
||||
(*dbd->del_admin_user)(user);
|
||||
}
|
||||
} else {
|
||||
if (dbd->del_user)
|
||||
if (dbd->del_user) {
|
||||
(*dbd->del_user)(user, realm);
|
||||
}
|
||||
}
|
||||
} else if (ct == TA_UPDATE_USER) {
|
||||
if (is_admin) {
|
||||
@ -976,8 +1034,9 @@ int adminuser(uint8_t *user, uint8_t *realm, uint8_t *pwd, uint8_t *secret, uint
|
||||
(*dbd->set_admin_user)(user, realm, password);
|
||||
}
|
||||
} else {
|
||||
if (dbd->set_user_key)
|
||||
if (dbd->set_user_key) {
|
||||
(*dbd->set_user_key)(user, realm, skey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1044,7 +1103,7 @@ void run_db_test(void) {
|
||||
oauth_key oak;
|
||||
char err_msg[1025];
|
||||
err_msg[0] = 0;
|
||||
if (convert_oauth_key_data(&oakd, &oak, err_msg, sizeof(err_msg) - 1) < 0) {
|
||||
if (!convert_oauth_key_data(&oakd, &oak, err_msg, sizeof(err_msg) - 1)) {
|
||||
printf(" ERROR: %s\n", err_msg);
|
||||
} else {
|
||||
printf(" OK!\n");
|
||||
@ -1152,8 +1211,9 @@ ip_range_list_t *get_ip_list(const char *kind) {
|
||||
|
||||
void ip_list_free(ip_range_list_t *l) {
|
||||
if (l) {
|
||||
if (l->rs)
|
||||
if (l->rs) {
|
||||
free(l->rs);
|
||||
}
|
||||
free(l);
|
||||
}
|
||||
}
|
||||
@ -1209,16 +1269,18 @@ int add_ip_list_range(const char *range0, const char *realm, ip_range_list_t *li
|
||||
addr_cpy(&max, &min);
|
||||
}
|
||||
|
||||
if (separator)
|
||||
if (separator) {
|
||||
*separator = '-';
|
||||
}
|
||||
|
||||
++(list->ranges_number);
|
||||
list->rs = (ip_range_t *)realloc(list->rs, sizeof(ip_range_t) * list->ranges_number);
|
||||
STRCPY(list->rs[list->ranges_number - 1].str, range);
|
||||
if (realm)
|
||||
if (realm) {
|
||||
STRCPY(list->rs[list->ranges_number - 1].realm, realm);
|
||||
else
|
||||
} else {
|
||||
list->rs[list->ranges_number - 1].realm[0] = 0;
|
||||
}
|
||||
free(range);
|
||||
ioa_addr_range_set(&(list->rs[list->ranges_number - 1].enc), &min, &max);
|
||||
|
||||
@ -1253,8 +1315,9 @@ int check_ip_list_range(const char *range0) {
|
||||
addr_cpy(&max, &min);
|
||||
}
|
||||
|
||||
if (separator)
|
||||
if (separator) {
|
||||
*separator = '-';
|
||||
}
|
||||
|
||||
free(range);
|
||||
|
||||
|
||||
@ -46,6 +46,14 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifndef _MSC_VER
|
||||
#include <stdatomic.h>
|
||||
extern _Atomic
|
||||
#else
|
||||
extern volatile
|
||||
#endif
|
||||
size_t global_allocation_count;
|
||||
|
||||
//////////// REALM //////////////
|
||||
|
||||
struct _realm_status_t;
|
||||
|
||||
@ -65,7 +65,6 @@ void print_field5769(const char *name, const void *f0, size_t len) {
|
||||
}
|
||||
|
||||
static int check_oauth(void) {
|
||||
|
||||
const char server_name[33] = "blackdow.carleon.gov";
|
||||
|
||||
size_t i_encs;
|
||||
@ -74,7 +73,7 @@ static int check_oauth(void) {
|
||||
|
||||
size_t ltp_output_length = 0;
|
||||
|
||||
const char *base64encoded_ltp =
|
||||
char *base64encoded_ltp =
|
||||
base64_encode((const unsigned char *)long_term_key, strlen(long_term_key), <p_output_length);
|
||||
|
||||
const char mac_key[33] = "ZksjpweoixXmvn67534m";
|
||||
@ -90,13 +89,12 @@ static int check_oauth(void) {
|
||||
|
||||
{
|
||||
{
|
||||
|
||||
for (i_encs = 0; encs[i_encs]; ++i_encs) {
|
||||
|
||||
printf("oauth token %s:", encs[i_encs]);
|
||||
|
||||
if (print_extra)
|
||||
if (print_extra) {
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
oauth_token ot;
|
||||
memset(&ot, 0, sizeof(ot));
|
||||
@ -129,9 +127,9 @@ static int check_oauth(void) {
|
||||
char err_msg[1025] = "\0";
|
||||
size_t err_msg_size = sizeof(err_msg) - 1;
|
||||
|
||||
if (convert_oauth_key_data(&okd, &key, err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd, &key, err_msg, err_msg_size)) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,41 +143,41 @@ static int check_oauth(void) {
|
||||
encoded_oauth_token etoken;
|
||||
memset(&etoken, 0, sizeof(etoken));
|
||||
|
||||
if (encode_oauth_token((const uint8_t *)server_name, &etoken, &key, &ot, (const uint8_t *)gcm_nonce) < 0) {
|
||||
if (!encode_oauth_token((const uint8_t *)server_name, &etoken, &key, &ot, (const uint8_t *)gcm_nonce)) {
|
||||
fprintf(stderr, "%s: cannot encode oauth token\n", __FUNCTION__);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (print_extra) {
|
||||
print_field5769("encoded token", etoken.token, etoken.size);
|
||||
}
|
||||
|
||||
if (decode_oauth_token((const uint8_t *)server_name, &etoken, &key, &dot) < 0) {
|
||||
if (!decode_oauth_token((const uint8_t *)server_name, &etoken, &key, &dot)) {
|
||||
fprintf(stderr, "%s: cannot decode oauth token\n", __FUNCTION__);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp((char *)ot.enc_block.mac_key, (char *)dot.enc_block.mac_key)) {
|
||||
fprintf(stderr, "%s: wrong mac key: %s, must be %s\n", __FUNCTION__, (char *)dot.enc_block.mac_key,
|
||||
(char *)ot.enc_block.mac_key);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (ot.enc_block.key_length != dot.enc_block.key_length) {
|
||||
fprintf(stderr, "%s: wrong key length: %d, must be %d\n", __FUNCTION__, (int)dot.enc_block.key_length,
|
||||
(int)ot.enc_block.key_length);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
if (ot.enc_block.timestamp != dot.enc_block.timestamp) {
|
||||
fprintf(stderr, "%s: wrong timestamp: %llu, must be %llu\n", __FUNCTION__,
|
||||
(unsigned long long)dot.enc_block.timestamp, (unsigned long long)ot.enc_block.timestamp);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
if (ot.enc_block.lifetime != dot.enc_block.lifetime) {
|
||||
fprintf(stderr, "%s: wrong lifetime: %lu, must be %lu\n", __FUNCTION__, (unsigned long)dot.enc_block.lifetime,
|
||||
(unsigned long)ot.enc_block.lifetime);
|
||||
return -1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
printf("OK\n");
|
||||
@ -187,7 +185,16 @@ static int check_oauth(void) {
|
||||
}
|
||||
}
|
||||
|
||||
if (base64encoded_ltp) {
|
||||
free(base64encoded_ltp);
|
||||
}
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (base64encoded_ltp) {
|
||||
free(base64encoded_ltp);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////
|
||||
@ -200,8 +207,9 @@ int main(int argc, const char **argv) {
|
||||
UNUSED_ARG(argc);
|
||||
UNUSED_ARG(argv);
|
||||
|
||||
if (argc > 1)
|
||||
if (argc > 1) {
|
||||
print_extra = 1;
|
||||
}
|
||||
|
||||
set_logfile("stdout");
|
||||
set_no_stdout_log(1);
|
||||
@ -451,8 +459,7 @@ int main(int argc, const char **argv) {
|
||||
|
||||
printf("RFC 5769 IPv4 encoding result: ");
|
||||
|
||||
res = stun_attr_get_first_addr_str(buf, sizeof(respv4) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr4, NULL);
|
||||
if (res < 0) {
|
||||
if (!stun_attr_get_first_addr_str(buf, sizeof(respv4) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr4, NULL)) {
|
||||
printf("failure on message structure check\n");
|
||||
exit(-1);
|
||||
}
|
||||
@ -540,8 +547,7 @@ int main(int argc, const char **argv) {
|
||||
|
||||
printf("RFC 5769 IPv6 encoding result: ");
|
||||
|
||||
res = stun_attr_get_first_addr_str(buf, sizeof(respv6) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr6, NULL);
|
||||
if (res < 0) {
|
||||
if (!stun_attr_get_first_addr_str(buf, sizeof(respv6) - 1, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &addr6, NULL)) {
|
||||
printf("failure on message structure check\n");
|
||||
exit(-1);
|
||||
}
|
||||
@ -557,8 +563,9 @@ int main(int argc, const char **argv) {
|
||||
}
|
||||
|
||||
{
|
||||
if (check_oauth() < 0)
|
||||
if (check_oauth() < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@ -28,6 +28,7 @@
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -57,37 +58,42 @@ static int counter = 0;
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, int response_port, int change_ip,
|
||||
int change_port, int padding) {
|
||||
static int run_stunclient(const char *rip, int rport, int *port, bool *rfc5780, int response_port, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
|
||||
ioa_addr remote_addr;
|
||||
int new_udp_fd = -1;
|
||||
|
||||
memset((void *)&remote_addr, 0, sizeof(ioa_addr));
|
||||
if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0)
|
||||
if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (udp_fd < 0) {
|
||||
udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0);
|
||||
if (udp_fd < 0)
|
||||
if (udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (!addr_any(&real_local_addr)) {
|
||||
if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response_port >= 0) {
|
||||
|
||||
new_udp_fd = socket(remote_addr.ss.sa_family, SOCK_DGRAM, 0);
|
||||
if (new_udp_fd < 0)
|
||||
if (new_udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
addr_set_port(&real_local_addr, response_port);
|
||||
|
||||
if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
turn::StunMsgRequest req(STUN_METHOD_BINDING);
|
||||
@ -152,8 +158,9 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
len = sendto(udp_fd, req.getRawBuffer(), req.getSize(), 0, (struct sockaddr *)&remote_addr, (socklen_t)slen);
|
||||
} while (len < 0 && (socket_eintr() || socket_enobufs() || socket_eagain()));
|
||||
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) {
|
||||
@ -186,8 +193,9 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
}
|
||||
} while (len < 0 && socket_eintr());
|
||||
|
||||
if (recvd > 0)
|
||||
if (recvd > 0) {
|
||||
len = recvd;
|
||||
}
|
||||
buf.len = len;
|
||||
|
||||
try {
|
||||
@ -251,38 +259,43 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
|
||||
#else
|
||||
|
||||
static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, int response_port, int change_ip,
|
||||
int change_port, int padding) {
|
||||
static int run_stunclient(const char *rip, int rport, int *port, bool *rfc5780, int response_port, bool change_ip,
|
||||
bool change_port, int padding) {
|
||||
|
||||
ioa_addr remote_addr;
|
||||
int new_udp_fd = -1;
|
||||
stun_buffer buf;
|
||||
|
||||
memset(&remote_addr, 0, sizeof(remote_addr));
|
||||
if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0)
|
||||
if (make_ioa_addr((const uint8_t *)rip, rport, &remote_addr) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (udp_fd < 0) {
|
||||
udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
|
||||
if (udp_fd < 0)
|
||||
if (udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
if (!addr_any(&real_local_addr)) {
|
||||
if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (response_port >= 0) {
|
||||
|
||||
new_udp_fd = socket(remote_addr.ss.sa_family, CLIENT_DGRAM_SOCKET_TYPE, CLIENT_DGRAM_SOCKET_PROTOCOL);
|
||||
if (new_udp_fd < 0)
|
||||
if (new_udp_fd < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
|
||||
addr_set_port(&real_local_addr, response_port);
|
||||
|
||||
if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0)
|
||||
if (addr_bind(new_udp_fd, &real_local_addr, 0, 1, UDP_SOCKET) < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
stun_prepare_binding_request(&buf);
|
||||
@ -294,7 +307,7 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
stun_attr_add_change_request_str((uint8_t *)buf.buf, (size_t *)&(buf.len), change_ip, change_port);
|
||||
}
|
||||
if (padding) {
|
||||
if (stun_attr_add_padding_str((uint8_t *)buf.buf, (size_t *)&(buf.len), 1500) < 0) {
|
||||
if (!stun_attr_add_padding_str((uint8_t *)buf.buf, (size_t *)&(buf.len), 1500)) {
|
||||
printf("%s: ERROR: Cannot add padding\n", __FUNCTION__);
|
||||
}
|
||||
}
|
||||
@ -307,8 +320,9 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
len = sendto(udp_fd, buf.buf, buf.len, 0, (struct sockaddr *)&remote_addr, (socklen_t)slen);
|
||||
} while (len < 0 && (socket_eintr() || socket_enobufs() || socket_eagain()));
|
||||
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
err(-1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
if (addr_get_from_sock(udp_fd, &real_local_addr) < 0) {
|
||||
@ -340,8 +354,9 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
}
|
||||
} while (len < 0 && (socket_eintr() || socket_eagain()));
|
||||
|
||||
if (recvd > 0)
|
||||
if (recvd > 0) {
|
||||
len = recvd;
|
||||
}
|
||||
buf.len = len;
|
||||
|
||||
if (stun_is_command_message(&buf)) {
|
||||
@ -354,7 +369,7 @@ static int run_stunclient(const char *rip, int rport, int *port, int *rfc5780, i
|
||||
|
||||
ioa_addr reflexive_addr;
|
||||
addr_set_any(&reflexive_addr);
|
||||
if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &reflexive_addr, NULL) >= 0) {
|
||||
if (stun_attr_get_first_addr(&buf, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, &reflexive_addr, NULL)) {
|
||||
|
||||
stun_attr_ref sar = stun_attr_get_first_by_type_str(buf.buf, buf.len, STUN_ATTRIBUTE_OTHER_ADDRESS);
|
||||
if (sar) {
|
||||
@ -415,10 +430,11 @@ int main(int argc, char **argv) {
|
||||
int port = DEFAULT_STUN_PORT;
|
||||
char local_addr[256] = "\0";
|
||||
int c = 0;
|
||||
int forceRfc5780 = 0;
|
||||
bool forceRfc5780 = false;
|
||||
|
||||
if (socket_init())
|
||||
if (socket_init()) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
set_logfile("stdout");
|
||||
set_no_stdout_log(1);
|
||||
@ -457,7 +473,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
int local_port = -1;
|
||||
int rfc5780 = 0;
|
||||
bool rfc5780 = false;
|
||||
|
||||
run_stunclient(argv[optind], port, &local_port, &rfc5780, -1, 0, 0, 0);
|
||||
|
||||
|
||||
@ -8,7 +8,13 @@ set(SOURCE_FILES
|
||||
mainuclient.c
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES})
|
||||
set(HEADER_FILES
|
||||
uclient.h
|
||||
startuclient.h
|
||||
session.h
|
||||
)
|
||||
|
||||
add_executable(${PROJECT_NAME} ${SOURCE_FILES} ${HEADER_FILES})
|
||||
target_link_libraries(${PROJECT_NAME} PRIVATE turnclient)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES
|
||||
RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin
|
||||
@ -21,4 +27,4 @@ install(DIRECTORY
|
||||
$<TARGET_FILE_DIR:${PROJECT_NAME}>/
|
||||
DESTINATION DESTINATION "${CMAKE_INSTALL_BINDIR}"
|
||||
COMPONENT Runtime
|
||||
)
|
||||
)
|
||||
|
||||
@ -31,7 +31,6 @@
|
||||
#include "apputils.h"
|
||||
#include "ns_turn_utils.h"
|
||||
#include "session.h"
|
||||
#include "stun_buffer.h"
|
||||
#include "uclient.h"
|
||||
|
||||
#include <stdio.h>
|
||||
@ -48,22 +47,22 @@
|
||||
/////////////// extern definitions /////////////////////
|
||||
|
||||
int clmessage_length = 100;
|
||||
int do_not_use_channel = 0;
|
||||
int c2c = 0;
|
||||
bool do_not_use_channel = false;
|
||||
bool c2c = false;
|
||||
int clnet_verbose = TURN_VERBOSE_NONE;
|
||||
int use_tcp = 0;
|
||||
int use_sctp = 0;
|
||||
int use_secure = 0;
|
||||
int hang_on = 0;
|
||||
bool use_tcp = false;
|
||||
bool use_sctp = false;
|
||||
bool use_secure = false;
|
||||
bool hang_on = false;
|
||||
ioa_addr peer_addr;
|
||||
int no_rtcp = 0;
|
||||
bool no_rtcp = false;
|
||||
int default_address_family = STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT;
|
||||
int dont_fragment = 0;
|
||||
bool dont_fragment = false;
|
||||
uint8_t g_uname[STUN_MAX_USERNAME_SIZE + 1];
|
||||
password_t g_upwd;
|
||||
char g_auth_secret[1025] = "\0";
|
||||
int g_use_auth_secret_with_timestamp = 0;
|
||||
int use_fingerprints = 1;
|
||||
bool g_use_auth_secret_with_timestamp = false;
|
||||
bool use_fingerprints = true;
|
||||
|
||||
static char ca_cert_file[1025] = "";
|
||||
static char cipher_suite[1025] = "";
|
||||
@ -74,26 +73,26 @@ int root_tls_ctx_num = 0;
|
||||
|
||||
uint8_t relay_transport = STUN_ATTRIBUTE_TRANSPORT_UDP_VALUE;
|
||||
unsigned char client_ifname[1025] = "";
|
||||
int passive_tcp = 0;
|
||||
int mandatory_channel_padding = 0;
|
||||
int negative_test = 0;
|
||||
int negative_protocol_test = 0;
|
||||
int dos = 0;
|
||||
int random_disconnect = 0;
|
||||
bool passive_tcp = false;
|
||||
bool mandatory_channel_padding = false;
|
||||
bool negative_test = false;
|
||||
bool negative_protocol_test = false;
|
||||
bool dos = false;
|
||||
bool random_disconnect = false;
|
||||
|
||||
SHATYPE shatype = SHATYPE_DEFAULT;
|
||||
|
||||
int mobility = 0;
|
||||
bool mobility = false;
|
||||
|
||||
int no_permissions = 0;
|
||||
bool no_permissions = false;
|
||||
|
||||
int extra_requests = 0;
|
||||
bool extra_requests = false;
|
||||
|
||||
char origin[STUN_MAX_ORIGIN_SIZE + 1] = "\0";
|
||||
|
||||
band_limit_t bps = 0;
|
||||
|
||||
int dual_allocation = 0;
|
||||
bool dual_allocation = false;
|
||||
|
||||
int oauth = 0;
|
||||
oauth_key okey_array[3];
|
||||
@ -168,7 +167,7 @@ int main(int argc, char **argv) {
|
||||
int peer_port = PEER_DEFAULT_PORT;
|
||||
|
||||
char rest_api_separator = ':';
|
||||
int use_null_cipher = 0;
|
||||
bool use_null_cipher = false;
|
||||
|
||||
#if defined(WINDOWS)
|
||||
|
||||
@ -211,17 +210,17 @@ int main(int argc, char **argv) {
|
||||
char err_msg[1025] = "\0";
|
||||
size_t err_msg_size = sizeof(err_msg) - 1;
|
||||
|
||||
if (convert_oauth_key_data(&okd_array[0], &okey_array[0], err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd_array[0], &okey_array[0], err_msg, err_msg_size)) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (convert_oauth_key_data(&okd_array[1], &okey_array[1], err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd_array[1], &okey_array[1], err_msg, err_msg_size)) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
exit(-1);
|
||||
}
|
||||
|
||||
if (convert_oauth_key_data(&okd_array[2], &okey_array[2], err_msg, err_msg_size) < 0) {
|
||||
if (!convert_oauth_key_data(&okd_array[2], &okey_array[2], err_msg, err_msg_size)) {
|
||||
fprintf(stderr, "%s\n", err_msg);
|
||||
exit(-1);
|
||||
}
|
||||
@ -233,22 +232,22 @@ int main(int argc, char **argv) {
|
||||
STRCPY(origin, optarg);
|
||||
break;
|
||||
case 'B':
|
||||
random_disconnect = 1;
|
||||
random_disconnect = true;
|
||||
break;
|
||||
case 'G':
|
||||
extra_requests = 1;
|
||||
extra_requests = true;
|
||||
break;
|
||||
case 'F':
|
||||
STRCPY(cipher_suite, optarg);
|
||||
break;
|
||||
case 'I':
|
||||
no_permissions = 1;
|
||||
no_permissions = true;
|
||||
break;
|
||||
case 'M':
|
||||
mobility = 1;
|
||||
mobility = true;
|
||||
break;
|
||||
case 'E': {
|
||||
char *fn = find_config_file(optarg, 1);
|
||||
char *fn = find_config_file(optarg);
|
||||
if (!fn) {
|
||||
fprintf(stderr, "ERROR: file %s not found\n", optarg);
|
||||
exit(-1);
|
||||
@ -256,25 +255,25 @@ int main(int argc, char **argv) {
|
||||
STRCPY(ca_cert_file, fn);
|
||||
} break;
|
||||
case 'O':
|
||||
dos = 1;
|
||||
dos = true;
|
||||
break;
|
||||
case 'C':
|
||||
rest_api_separator = *optarg;
|
||||
break;
|
||||
case 'D':
|
||||
mandatory_channel_padding = 1;
|
||||
mandatory_channel_padding = true;
|
||||
break;
|
||||
case 'N':
|
||||
negative_test = 1;
|
||||
negative_test = true;
|
||||
break;
|
||||
case 'R':
|
||||
negative_protocol_test = 1;
|
||||
negative_protocol_test = true;
|
||||
break;
|
||||
case 'z':
|
||||
RTP_PACKET_INTERVAL = atoi(optarg);
|
||||
break;
|
||||
case 'Z':
|
||||
dual_allocation = 1;
|
||||
dual_allocation = true;
|
||||
break;
|
||||
case 'u':
|
||||
STRCPY(g_uname, optarg);
|
||||
@ -283,7 +282,7 @@ int main(int argc, char **argv) {
|
||||
STRCPY(g_upwd, optarg);
|
||||
break;
|
||||
case 'g':
|
||||
dont_fragment = 1;
|
||||
dont_fragment = true;
|
||||
break;
|
||||
case 'd':
|
||||
STRCPY(client_ifname, optarg);
|
||||
@ -298,7 +297,7 @@ int main(int argc, char **argv) {
|
||||
clmessage_length = atoi(optarg);
|
||||
break;
|
||||
case 's':
|
||||
do_not_use_channel = 1;
|
||||
do_not_use_channel = true;
|
||||
break;
|
||||
case 'n':
|
||||
messagenumber = atoi(optarg);
|
||||
@ -319,26 +318,26 @@ int main(int argc, char **argv) {
|
||||
clnet_verbose = TURN_VERBOSE_NORMAL;
|
||||
break;
|
||||
case 'h':
|
||||
hang_on = 1;
|
||||
hang_on = true;
|
||||
break;
|
||||
case 'c':
|
||||
no_rtcp = 1;
|
||||
no_rtcp = true;
|
||||
break;
|
||||
case 'm':
|
||||
mclient = atoi(optarg);
|
||||
break;
|
||||
case 'y':
|
||||
c2c = 1;
|
||||
c2c = true;
|
||||
break;
|
||||
case 't':
|
||||
use_tcp = 1;
|
||||
use_tcp = true;
|
||||
break;
|
||||
case 'b':
|
||||
use_sctp = 1;
|
||||
use_tcp = 1;
|
||||
use_sctp = true;
|
||||
use_tcp = true;
|
||||
break;
|
||||
case 'P':
|
||||
passive_tcp = 1;
|
||||
passive_tcp = true;
|
||||
/* implies 'T': */
|
||||
/* no break */
|
||||
/* Falls through. */
|
||||
@ -346,19 +345,19 @@ int main(int argc, char **argv) {
|
||||
relay_transport = STUN_ATTRIBUTE_TRANSPORT_TCP_VALUE;
|
||||
break;
|
||||
case 'U':
|
||||
use_null_cipher = 1;
|
||||
use_null_cipher = true;
|
||||
/* implies 'S' */
|
||||
/* no break */
|
||||
/* Falls through. */
|
||||
case 'S':
|
||||
use_secure = 1;
|
||||
use_secure = true;
|
||||
break;
|
||||
case 'W':
|
||||
g_use_auth_secret_with_timestamp = 1;
|
||||
g_use_auth_secret_with_timestamp = true;
|
||||
STRCPY(g_auth_secret, optarg);
|
||||
break;
|
||||
case 'i': {
|
||||
char *fn = find_config_file(optarg, 1);
|
||||
char *fn = find_config_file(optarg);
|
||||
if (!fn) {
|
||||
fprintf(stderr, "ERROR: file %s not found\n", optarg);
|
||||
exit(-1);
|
||||
@ -367,7 +366,7 @@ int main(int argc, char **argv) {
|
||||
free(fn);
|
||||
} break;
|
||||
case 'k': {
|
||||
char *fn = find_config_file(optarg, 1);
|
||||
char *fn = find_config_file(optarg);
|
||||
if (!fn) {
|
||||
fprintf(stderr, "ERROR: file %s not found\n", optarg);
|
||||
exit(-1);
|
||||
@ -382,7 +381,7 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (dual_allocation) {
|
||||
no_rtcp = 1;
|
||||
no_rtcp = true;
|
||||
}
|
||||
|
||||
if (g_use_auth_secret_with_timestamp) {
|
||||
@ -419,7 +418,7 @@ int main(int argc, char **argv) {
|
||||
hmac[0] = 0;
|
||||
|
||||
if (stun_calculate_hmac(g_uname, strlen((char *)g_uname), (uint8_t *)g_auth_secret, strlen(g_auth_secret), hmac,
|
||||
&hmac_len, shatype) >= 0) {
|
||||
&hmac_len, shatype)) {
|
||||
size_t pwd_length = 0;
|
||||
char *pwd = base64_encode(hmac, hmac_len, &pwd_length);
|
||||
|
||||
@ -435,22 +434,24 @@ int main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if (is_TCP_relay()) {
|
||||
dont_fragment = 0;
|
||||
no_rtcp = 1;
|
||||
c2c = 1;
|
||||
use_tcp = 1;
|
||||
do_not_use_channel = 1;
|
||||
dont_fragment = false;
|
||||
no_rtcp = true;
|
||||
c2c = true;
|
||||
use_tcp = true;
|
||||
do_not_use_channel = true;
|
||||
}
|
||||
|
||||
if (port == 0) {
|
||||
if (use_secure)
|
||||
if (use_secure) {
|
||||
port = DEFAULT_STUN_TLS_PORT;
|
||||
else
|
||||
} else {
|
||||
port = DEFAULT_STUN_PORT;
|
||||
}
|
||||
}
|
||||
|
||||
if (clmessage_length < (int)sizeof(message_info))
|
||||
if (clmessage_length < (int)sizeof(message_info)) {
|
||||
clmessage_length = (int)sizeof(message_info);
|
||||
}
|
||||
|
||||
const int max_header = 100;
|
||||
if (clmessage_length > (int)(STUN_BUFFER_SIZE - max_header)) {
|
||||
@ -488,46 +489,23 @@ int main(int argc, char **argv) {
|
||||
OpenSSL_add_ssl_algorithms();
|
||||
|
||||
const char *csuite = "ALL"; //"AES256-SHA" "DH"
|
||||
if (use_null_cipher)
|
||||
if (use_null_cipher) {
|
||||
csuite = "eNULL";
|
||||
else if (cipher_suite[0])
|
||||
} else if (cipher_suite[0]) {
|
||||
csuite = cipher_suite;
|
||||
}
|
||||
|
||||
if (use_tcp) {
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
#if TLSv1_2_SUPPORTED
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_2_client_method());
|
||||
#elif TLSv1_1_SUPPORTED
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_1_client_method());
|
||||
#else
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLSv1_client_method());
|
||||
#endif
|
||||
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
|
||||
#else // OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(TLS_client_method());
|
||||
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
|
||||
#endif
|
||||
root_tls_ctx_num++;
|
||||
} else {
|
||||
#if !DTLS_SUPPORTED
|
||||
fprintf(stderr, "ERROR: DTLS is not supported.\n");
|
||||
exit(-1);
|
||||
#else
|
||||
#if OPENSSL_VERSION_NUMBER < 0x10100000L
|
||||
if (OPENSSL_VERSION_NUMBER < 0x10000000L) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,
|
||||
"WARNING: OpenSSL version is rather old, DTLS may not be working correctly.\n");
|
||||
}
|
||||
#if DTLSv1_2_SUPPORTED
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_2_client_method());
|
||||
#else
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLSv1_client_method());
|
||||
#endif
|
||||
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
|
||||
#else // OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
root_tls_ctx[root_tls_ctx_num] = SSL_CTX_new(DTLS_client_method());
|
||||
SSL_CTX_set_cipher_list(root_tls_ctx[root_tls_ctx_num], csuite);
|
||||
#endif
|
||||
#endif
|
||||
root_tls_ctx_num++;
|
||||
}
|
||||
|
||||
@ -35,12 +35,11 @@
|
||||
#include <event2/event.h>
|
||||
|
||||
#include "ns_turn_ioaddr.h"
|
||||
#include "ns_turn_utils.h"
|
||||
|
||||
#include "apputils.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
#include "ns_turn_openssl.h"
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -48,19 +47,17 @@ extern "C" {
|
||||
|
||||
///////// types ////////////
|
||||
|
||||
enum _UR_STATE { UR_STATE_UNKNOWN = 0, UR_STATE_READY, UR_STATE_DONE };
|
||||
|
||||
typedef enum _UR_STATE UR_STATE;
|
||||
typedef enum { UR_STATE_UNKNOWN = 0, UR_STATE_READY, UR_STATE_DONE } UR_STATE;
|
||||
|
||||
//////////////// session info //////////////////////
|
||||
|
||||
typedef struct {
|
||||
/* RFC 6062 */
|
||||
uint32_t cid;
|
||||
uint32_t cid; // https://datatracker.ietf.org/doc/html/rfc6062#section-6.2.1
|
||||
ioa_addr tcp_data_local_addr;
|
||||
ioa_socket_raw tcp_data_fd;
|
||||
SSL *tcp_data_ssl;
|
||||
int tcp_data_bound;
|
||||
bool tcp_data_bound;
|
||||
} app_tcp_conn_info;
|
||||
|
||||
typedef struct {
|
||||
@ -73,30 +70,30 @@ typedef struct {
|
||||
ioa_addr relay_addr;
|
||||
ioa_socket_raw fd;
|
||||
SSL *ssl;
|
||||
int broken;
|
||||
bool broken;
|
||||
uint8_t nonce[STUN_MAX_NONCE_SIZE + 1];
|
||||
uint8_t realm[STUN_MAX_REALM_SIZE + 1];
|
||||
/* oAuth */
|
||||
int oauth;
|
||||
bool oauth;
|
||||
uint8_t server_name[STUN_MAX_SERVER_NAME_SIZE + 1];
|
||||
hmackey_t key;
|
||||
int key_set;
|
||||
int cok;
|
||||
bool key_set;
|
||||
int cok; // presumably means "client oauth key" or something like it? Appears to be used as an index into an array.
|
||||
/* RFC 6062 */
|
||||
app_tcp_conn_info **tcp_conn;
|
||||
size_t tcp_conn_number;
|
||||
int is_peer;
|
||||
bool is_peer;
|
||||
char s_mobile_id[33];
|
||||
} app_ur_conn_info;
|
||||
|
||||
typedef struct {
|
||||
app_ur_conn_info pinfo;
|
||||
UR_STATE state;
|
||||
unsigned int ctime;
|
||||
unsigned int ctime; // assigned to from a uint64_t variable "current time" likely should be a time_t or similar.
|
||||
uint16_t chnum;
|
||||
int wait_cycles;
|
||||
int timer_cycle;
|
||||
int completed;
|
||||
int completed; // A count of the number of connections considered complete.
|
||||
struct event *input_ev;
|
||||
struct event *input_tcp_data_ev;
|
||||
stun_buffer in_buffer;
|
||||
@ -118,7 +115,7 @@ typedef struct {
|
||||
|
||||
///////////////////////////////////////////////////////
|
||||
|
||||
typedef struct _message_info {
|
||||
typedef struct {
|
||||
int msgnum;
|
||||
uint64_t mstime;
|
||||
} message_info;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -31,8 +31,9 @@
|
||||
#ifndef __STARTCLIENT_TURN__
|
||||
#define __STARTCLIENT_TURN__
|
||||
|
||||
#include "ns_turn_utils.h"
|
||||
#include "ns_turn_ioaddr.h" // for ioa_addr
|
||||
#include "session.h"
|
||||
#include "stun_buffer.h" // for stun_buffer
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
@ -46,17 +47,17 @@ int not_rare_event(void);
|
||||
void add_origin(stun_buffer *message);
|
||||
|
||||
int start_c2c_connection(uint16_t clnet_remote_port, const char *remote_address, const unsigned char *ifname,
|
||||
const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe,
|
||||
const char *local_address, bool verbose, app_ur_conn_info *clnet_info_probe,
|
||||
app_ur_conn_info *clnet_info1, uint16_t *chn1, app_ur_conn_info *clnet_info1_rtcp,
|
||||
uint16_t *chn1_rtcp, app_ur_conn_info *clnet_info2, uint16_t *chn2,
|
||||
app_ur_conn_info *clnet_info2_rtcp, uint16_t *chn2_rtcp);
|
||||
|
||||
int start_connection(uint16_t clnet_remote_port, const char *remote_address, const unsigned char *ifname,
|
||||
const char *local_address, int verbose, app_ur_conn_info *clnet_info_probe,
|
||||
const char *local_address, bool verbose, app_ur_conn_info *clnet_info_probe,
|
||||
app_ur_conn_info *clnet_info, uint16_t *chn, app_ur_conn_info *clnet_info_rtcp,
|
||||
uint16_t *chn_rtcp);
|
||||
|
||||
int turn_tcp_connect(int verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_addr);
|
||||
int turn_tcp_connect(bool verbose, app_ur_conn_info *clnet_info, ioa_addr *peer_addr);
|
||||
|
||||
void tcp_data_connect(app_ur_session *elem, uint32_t cid);
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@
|
||||
|
||||
#include "uclient.h"
|
||||
#include "apputils.h"
|
||||
#include "ns_turn_ioalib.h"
|
||||
#include "ns_turn_utils.h"
|
||||
#include "session.h"
|
||||
#include "startuclient.h"
|
||||
@ -40,11 +41,17 @@
|
||||
#endif
|
||||
#include <time.h>
|
||||
|
||||
#if defined(__MINGW32__)
|
||||
#ifndef usleep
|
||||
#define usleep Sleep
|
||||
#endif
|
||||
#endif
|
||||
|
||||
static int verbose_packets = 0;
|
||||
|
||||
static size_t current_clients_number = 0;
|
||||
|
||||
static int start_full_timer = 0;
|
||||
static bool start_full_timer = false;
|
||||
static uint32_t tot_messages = 0;
|
||||
static uint32_t tot_send_messages = 0;
|
||||
static uint64_t tot_send_bytes = 0;
|
||||
@ -84,7 +91,7 @@ static uint64_t max_latency = 0;
|
||||
static uint64_t min_jitter = 0xFFFFFFFF;
|
||||
static uint64_t max_jitter = 0;
|
||||
|
||||
static int show_statistics = 0;
|
||||
static bool show_statistics = false;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@ -96,10 +103,12 @@ static void __turn_getMSTime(void) {
|
||||
#else
|
||||
tp.tv_sec = time(NULL);
|
||||
#endif
|
||||
if (!start_sec)
|
||||
if (!start_sec) {
|
||||
start_sec = tp.tv_sec;
|
||||
if (current_time != (uint64_t)((uint64_t)(tp.tv_sec) - start_sec))
|
||||
show_statistics = 1;
|
||||
}
|
||||
if (current_time != (uint64_t)((uint64_t)(tp.tv_sec) - start_sec)) {
|
||||
show_statistics = true;
|
||||
}
|
||||
current_time = (uint64_t)((uint64_t)(tp.tv_sec) - start_sec);
|
||||
current_mstime = (uint64_t)((current_time * 1000) + (tp.tv_nsec / 1000000));
|
||||
}
|
||||
@ -128,8 +137,7 @@ static void uc_delete_session_elem_data(app_ur_session *cdi) {
|
||||
EVENT_DEL(cdi->input_ev);
|
||||
EVENT_DEL(cdi->input_tcp_data_ev);
|
||||
if (cdi->pinfo.tcp_conn) {
|
||||
int i = 0;
|
||||
for (i = 0; i < (int)(cdi->pinfo.tcp_conn_number); ++i) {
|
||||
for (int i = 0; i < (int)(cdi->pinfo.tcp_conn_number); ++i) {
|
||||
if (cdi->pinfo.tcp_conn[i]) {
|
||||
if (cdi->pinfo.tcp_conn[i]->tcp_data_ssl && !(cdi->pinfo.broken)) {
|
||||
if (!(SSL_get_shutdown(cdi->pinfo.tcp_conn[i]->tcp_data_ssl) & SSL_SENT_SHUTDOWN)) {
|
||||
@ -182,7 +190,7 @@ static int remove_all_from_ss(app_ur_session *ss) {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_connection, app_tcp_conn_info *atc) {
|
||||
int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, bool data_connection, app_tcp_conn_info *atc) {
|
||||
|
||||
int rc = 0;
|
||||
int ret = -1;
|
||||
@ -216,7 +224,7 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
|
||||
if (ssl) {
|
||||
|
||||
int message_sent = 0;
|
||||
bool message_sent = false;
|
||||
while (!message_sent) {
|
||||
|
||||
if (SSL_get_shutdown(ssl)) {
|
||||
@ -233,7 +241,7 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "buffer sent: size=%d\n", len);
|
||||
}
|
||||
|
||||
message_sent = 1;
|
||||
message_sent = true;
|
||||
ret = len;
|
||||
} else {
|
||||
switch (SSL_get_error(ssl, len)) {
|
||||
@ -251,8 +259,9 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket write error 111.666: \n");
|
||||
if (handle_socket_error())
|
||||
if (handle_socket_error()) {
|
||||
break;
|
||||
}
|
||||
/* Falls through. */
|
||||
case SSL_ERROR_SSL: {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n");
|
||||
@ -262,7 +271,7 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
}
|
||||
/* Falls through. */
|
||||
default:
|
||||
clnet_info->broken = 1;
|
||||
clnet_info->broken = true;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while writing!\n");
|
||||
return -1;
|
||||
}
|
||||
@ -271,7 +280,7 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
|
||||
} else if (fd >= 0) {
|
||||
|
||||
size_t left = (size_t)(message->len);
|
||||
size_t left = message->len;
|
||||
|
||||
while (left > 0) {
|
||||
do {
|
||||
@ -286,8 +295,9 @@ int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_con
|
||||
}
|
||||
}
|
||||
|
||||
if (left > 0)
|
||||
if (left > 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = (int)message->len;
|
||||
}
|
||||
@ -304,8 +314,9 @@ static int wait_fd(int fd, unsigned int cycle) {
|
||||
FD_ZERO(&fds);
|
||||
FD_SET(fd, &fds);
|
||||
|
||||
if (dos && cycle == 0)
|
||||
if (dos && cycle == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct timeval start_time;
|
||||
struct timeval ctime;
|
||||
@ -323,8 +334,9 @@ static int wait_fd(int fd, unsigned int cycle) {
|
||||
} else {
|
||||
|
||||
timeout.tv_sec = 1;
|
||||
while (--cycle)
|
||||
while (--cycle) {
|
||||
timeout.tv_sec = timeout.tv_sec + timeout.tv_sec;
|
||||
}
|
||||
|
||||
if (ctime.tv_sec > start_time.tv_sec) {
|
||||
if (ctime.tv_sec >= start_time.tv_sec + timeout.tv_sec) {
|
||||
@ -346,7 +358,7 @@ static int wait_fd(int fd, unsigned int cycle) {
|
||||
}
|
||||
}
|
||||
|
||||
int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int sync, int data_connection,
|
||||
int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, bool sync, bool data_connection,
|
||||
app_tcp_conn_info *atc, stun_buffer *request_message) {
|
||||
|
||||
int rc = 0;
|
||||
@ -360,12 +372,14 @@ int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int sync, in
|
||||
}
|
||||
|
||||
ioa_socket_raw fd = clnet_info->fd;
|
||||
if (atc)
|
||||
if (atc) {
|
||||
fd = atc->tcp_data_fd;
|
||||
}
|
||||
|
||||
SSL *ssl = clnet_info->ssl;
|
||||
if (atc)
|
||||
if (atc) {
|
||||
ssl = atc->tcp_data_ssl;
|
||||
}
|
||||
|
||||
recv_again:
|
||||
|
||||
@ -374,13 +388,15 @@ recv_again:
|
||||
unsigned int cycle = 0;
|
||||
while (cycle < MAX_LISTENING_CYCLE_NUMBER) {
|
||||
int serc = wait_fd(fd, cycle);
|
||||
if (serc > 0)
|
||||
if (serc > 0) {
|
||||
break;
|
||||
}
|
||||
if (serc < 0) {
|
||||
return -1;
|
||||
}
|
||||
if (send_buffer(clnet_info, request_message, data_connection, atc) <= 0)
|
||||
if (send_buffer(clnet_info, request_message, data_connection, atc) <= 0) {
|
||||
return -1;
|
||||
}
|
||||
++cycle;
|
||||
}
|
||||
}
|
||||
@ -407,14 +423,16 @@ recv_again:
|
||||
int cycle = 0;
|
||||
while (!message_received && cycle++ < 100) {
|
||||
|
||||
if (SSL_get_shutdown(ssl))
|
||||
if (SSL_get_shutdown(ssl)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
rc = 0;
|
||||
do {
|
||||
rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1);
|
||||
if (rc < 0 && socket_eagain() && sync)
|
||||
if (rc < 0 && socket_eagain() && sync) {
|
||||
continue;
|
||||
}
|
||||
} while (rc < 0 && socket_eintr());
|
||||
|
||||
if (rc > 0) {
|
||||
@ -444,8 +462,9 @@ recv_again:
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket read error 111.999: \n");
|
||||
if (handle_socket_error())
|
||||
if (handle_socket_error()) {
|
||||
break;
|
||||
}
|
||||
/* Falls through. */
|
||||
case SSL_ERROR_SSL: {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n");
|
||||
@ -455,13 +474,14 @@ recv_again:
|
||||
}
|
||||
/* Falls through. */
|
||||
default:
|
||||
clnet_info->broken = 1;
|
||||
clnet_info->broken = true;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading: rc=%d, sslerr=%d\n", rc, sslerr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!sync)
|
||||
if (!sync) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -469,17 +489,19 @@ recv_again:
|
||||
|
||||
/* TLS*/
|
||||
|
||||
int message_received = 0;
|
||||
bool message_received = false;
|
||||
int cycle = 0;
|
||||
while (!message_received && cycle++ < 100) {
|
||||
|
||||
if (SSL_get_shutdown(ssl))
|
||||
if (SSL_get_shutdown(ssl)) {
|
||||
return -1;
|
||||
}
|
||||
rc = 0;
|
||||
do {
|
||||
rc = SSL_read(ssl, message->buf, sizeof(message->buf) - 1);
|
||||
if (rc < 0 && socket_eagain() && sync)
|
||||
if (rc < 0 && socket_eagain() && sync) {
|
||||
continue;
|
||||
}
|
||||
} while (rc < 0 && socket_eintr());
|
||||
|
||||
if (rc > 0) {
|
||||
@ -488,7 +510,7 @@ recv_again:
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "response received: size=%d\n", rc);
|
||||
}
|
||||
message->len = rc;
|
||||
message_received = 1;
|
||||
message_received = true;
|
||||
|
||||
} else {
|
||||
|
||||
@ -509,8 +531,9 @@ recv_again:
|
||||
break;
|
||||
case SSL_ERROR_SYSCALL:
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Socket read error 111.999: \n");
|
||||
if (handle_socket_error())
|
||||
if (handle_socket_error()) {
|
||||
break;
|
||||
}
|
||||
/* Falls through. */
|
||||
case SSL_ERROR_SSL: {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SSL write error: \n");
|
||||
@ -520,13 +543,14 @@ recv_again:
|
||||
}
|
||||
/* Falls through. */
|
||||
default:
|
||||
clnet_info->broken = 1;
|
||||
clnet_info->broken = true;
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Unexpected error while reading: rc=%d, sslerr=%d\n", rc, sslerr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!sync)
|
||||
if (!sync) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -544,11 +568,13 @@ recv_again:
|
||||
if (!atc) {
|
||||
mlen = stun_get_message_len_str(message->buf, rc, 1, &app_msg_len);
|
||||
} else {
|
||||
if (!sync)
|
||||
if (!sync) {
|
||||
mlen = clmessage_length;
|
||||
}
|
||||
|
||||
if (mlen > clmessage_length)
|
||||
if (mlen > clmessage_length) {
|
||||
mlen = clmessage_length;
|
||||
}
|
||||
|
||||
app_msg_len = (size_t)mlen;
|
||||
}
|
||||
@ -563,12 +589,14 @@ recv_again:
|
||||
rcr = recv(fd, message->buf + rsf, (size_t)mlen - (size_t)rsf, 0);
|
||||
} while (rcr < 0 && (socket_eintr() || (socket_eagain() && sync)));
|
||||
|
||||
if (rcr > 0)
|
||||
if (rcr > 0) {
|
||||
rsf += rcr;
|
||||
}
|
||||
}
|
||||
|
||||
if (rsf < 1)
|
||||
if (rsf < 1) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (rsf < (int)app_msg_len) {
|
||||
if ((size_t)(app_msg_len / (size_t)rsf) * ((size_t)(rsf)) != app_msg_len) {
|
||||
@ -613,11 +641,13 @@ recv_again:
|
||||
|
||||
static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info *atc) {
|
||||
|
||||
if (!elem)
|
||||
if (!elem) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (elem->state != UR_STATE_READY)
|
||||
if (elem->state != UR_STATE_READY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elem->ctime = current_time;
|
||||
|
||||
@ -644,13 +674,13 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
uint16_t chnumber = 0;
|
||||
|
||||
message_info mi;
|
||||
int miset = 0;
|
||||
bool miset = false;
|
||||
size_t buffers = 1;
|
||||
|
||||
if (is_tcp_data) {
|
||||
if ((int)elem->in_buffer.len == clmessage_length) {
|
||||
memcpy(&mi, (elem->in_buffer.buf), sizeof(message_info));
|
||||
miset = 1;
|
||||
miset = true;
|
||||
} else {
|
||||
/* TODO: make a more clean fix */
|
||||
buffers = (int)elem->in_buffer.len / clmessage_length;
|
||||
@ -700,14 +730,15 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
const uint8_t *data = stun_attr_get_value(sar);
|
||||
|
||||
memcpy(&mi, data, sizeof(message_info));
|
||||
miset = 1;
|
||||
miset = true;
|
||||
}
|
||||
|
||||
} else if (stun_is_success_response(&(elem->in_buffer))) {
|
||||
|
||||
if (elem->pinfo.nonce[0]) {
|
||||
if (check_integrity(&(elem->pinfo), &(elem->in_buffer)) < 0)
|
||||
if (check_integrity(&(elem->pinfo), &(elem->in_buffer)) < 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) {
|
||||
@ -725,7 +756,7 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
}
|
||||
|
||||
return rc;
|
||||
} else if (stun_is_challenge_response_str(elem->in_buffer.buf, (size_t)elem->in_buffer.len, &err_code, err_msg,
|
||||
} else if (stun_is_challenge_response_str(elem->in_buffer.buf, elem->in_buffer.len, &err_code, err_msg,
|
||||
sizeof(err_msg), clnet_info->realm, clnet_info->nonce,
|
||||
clnet_info->server_name, &(clnet_info->oauth))) {
|
||||
if (is_TCP_relay() && (stun_get_method(&(elem->in_buffer)) == STUN_METHOD_CONNECT)) {
|
||||
@ -751,7 +782,7 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
}
|
||||
|
||||
memcpy(&mi, elem->in_buffer.buf + 4, sizeof(message_info));
|
||||
miset = 1;
|
||||
miset = true;
|
||||
applen = elem->in_buffer.len - 4;
|
||||
}
|
||||
} else {
|
||||
@ -764,22 +795,26 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
printf("%s: 111.111: msgnum=%d, rmsgnum=%d, sent=%lu, recv=%lu\n",__FUNCTION__,
|
||||
mi->msgnum,elem->recvmsgnum,(unsigned long)mi->mstime,(unsigned long)current_mstime);
|
||||
*/
|
||||
if (mi.msgnum != elem->recvmsgnum + 1)
|
||||
if (mi.msgnum != elem->recvmsgnum + 1) {
|
||||
++(elem->loss);
|
||||
else {
|
||||
} else {
|
||||
uint64_t clatency = (uint64_t)time_minus(current_mstime, mi.mstime);
|
||||
if (clatency > max_latency)
|
||||
if (clatency > max_latency) {
|
||||
max_latency = clatency;
|
||||
if (clatency < min_latency)
|
||||
}
|
||||
if (clatency < min_latency) {
|
||||
min_latency = clatency;
|
||||
}
|
||||
elem->latency += clatency;
|
||||
if (elem->rmsgnum > 0) {
|
||||
uint64_t cjitter = abs((int)(current_mstime - elem->recvtimems) - RTP_PACKET_INTERVAL);
|
||||
|
||||
if (cjitter > max_jitter)
|
||||
if (cjitter > max_jitter) {
|
||||
max_jitter = cjitter;
|
||||
if (cjitter < min_jitter)
|
||||
}
|
||||
if (cjitter < min_jitter) {
|
||||
min_jitter = cjitter;
|
||||
}
|
||||
|
||||
elem->jitter += cjitter;
|
||||
}
|
||||
@ -790,10 +825,11 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
|
||||
elem->rmsgnum += buffers;
|
||||
tot_recv_messages += buffers;
|
||||
if (applen > 0)
|
||||
if (applen > 0) {
|
||||
tot_recv_bytes += applen;
|
||||
else
|
||||
} else {
|
||||
tot_recv_bytes += elem->in_buffer.len;
|
||||
}
|
||||
elem->recvtimems = current_mstime;
|
||||
elem->wait_cycles = 0;
|
||||
|
||||
@ -808,8 +844,9 @@ static int client_read(app_ur_session *elem, int is_tcp_data, app_tcp_conn_info
|
||||
|
||||
static int client_shutdown(app_ur_session *elem) {
|
||||
|
||||
if (!elem)
|
||||
if (!elem) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elem->state = UR_STATE_DONE;
|
||||
|
||||
@ -817,19 +854,22 @@ static int client_shutdown(app_ur_session *elem) {
|
||||
|
||||
remove_all_from_ss(elem);
|
||||
|
||||
if (clnet_verbose)
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "done, connection 0x%lx closed.\n", (long)elem);
|
||||
if (clnet_verbose) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "done, connection %p closed.\n", elem);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int client_write(app_ur_session *elem) {
|
||||
|
||||
if (!elem)
|
||||
if (!elem) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (elem->state != UR_STATE_READY)
|
||||
if (elem->state != UR_STATE_READY) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
elem->ctime = current_time;
|
||||
|
||||
@ -859,7 +899,7 @@ static int client_write(app_ur_session *elem) {
|
||||
int i = (unsigned int)(turn_random()) % elem->pinfo.tcp_conn_number;
|
||||
atc = elem->pinfo.tcp_conn[i];
|
||||
if (!atc->tcp_data_bound) {
|
||||
printf("%s: Uninitialized atc: i=%d, atc=0x%lx\n", __FUNCTION__, i, (long)atc);
|
||||
printf("%s: Uninitialized atc: i=%d, atc=%p\n", __FUNCTION__, i, atc);
|
||||
return -1;
|
||||
}
|
||||
} else if (!do_not_use_channel) {
|
||||
@ -870,11 +910,13 @@ static int client_write(app_ur_session *elem) {
|
||||
stun_init_indication(STUN_METHOD_SEND, &(elem->out_buffer));
|
||||
stun_attr_add(&(elem->out_buffer), STUN_ATTRIBUTE_DATA, buffer_to_send, clmessage_length);
|
||||
stun_attr_add_addr(&(elem->out_buffer), STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr));
|
||||
if (dont_fragment)
|
||||
if (dont_fragment) {
|
||||
stun_attr_add(&(elem->out_buffer), STUN_ATTRIBUTE_DONT_FRAGMENT, NULL, 0);
|
||||
}
|
||||
|
||||
if (use_fingerprints)
|
||||
if (use_fingerprints) {
|
||||
stun_attr_add_fingerprint_str(elem->out_buffer.buf, (size_t *)&(elem->out_buffer.len));
|
||||
}
|
||||
}
|
||||
|
||||
if (elem->out_buffer.len > 0) {
|
||||
@ -904,8 +946,9 @@ static int client_write(app_ur_session *elem) {
|
||||
|
||||
void client_input_handler(evutil_socket_t fd, short what, void *arg) {
|
||||
|
||||
if (!(what & EV_READ) || !arg)
|
||||
if (!(what & EV_READ) || !arg) {
|
||||
return;
|
||||
}
|
||||
|
||||
UNUSED_ARG(fd);
|
||||
|
||||
@ -932,8 +975,9 @@ void client_input_handler(evutil_socket_t fd, short what, void *arg) {
|
||||
}
|
||||
}
|
||||
int rc = client_read(elem, is_tcp_data, atc);
|
||||
if (rc <= 0)
|
||||
if (rc <= 0) {
|
||||
break;
|
||||
}
|
||||
} while (1);
|
||||
|
||||
break;
|
||||
@ -965,8 +1009,9 @@ static int start_client(const char *remote_address, int port, const unsigned cha
|
||||
app_ur_session *ss = create_new_ss();
|
||||
app_ur_session *ss_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
ss_rtcp = create_new_ss();
|
||||
}
|
||||
|
||||
app_ur_conn_info clnet_info_probe; /* for load balancing probe */
|
||||
memset(&clnet_info_probe, 0, sizeof(clnet_info_probe));
|
||||
@ -975,8 +1020,9 @@ static int start_client(const char *remote_address, int port, const unsigned cha
|
||||
app_ur_conn_info *clnet_info = &(ss->pinfo);
|
||||
app_ur_conn_info *clnet_info_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
clnet_info_rtcp = &(ss_rtcp->pinfo);
|
||||
}
|
||||
|
||||
uint16_t chnum = 0;
|
||||
uint16_t chnum_rtcp = 0;
|
||||
@ -994,8 +1040,9 @@ static int start_client(const char *remote_address, int port, const unsigned cha
|
||||
|
||||
socket_set_nonblocking(clnet_info->fd);
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
socket_set_nonblocking(clnet_info_rtcp->fd);
|
||||
}
|
||||
|
||||
struct event *ev = event_new(client_event_base, clnet_info->fd, EV_READ | EV_PERSIST, client_input_handler, ss);
|
||||
|
||||
@ -1022,8 +1069,9 @@ static int start_client(const char *remote_address, int port, const unsigned cha
|
||||
|
||||
ss_rtcp->input_ev = ev_rtcp;
|
||||
ss_rtcp->tot_msgnum = ss->tot_msgnum;
|
||||
if (ss_rtcp->tot_msgnum < 1)
|
||||
if (ss_rtcp->tot_msgnum < 1) {
|
||||
ss_rtcp->tot_msgnum = 1;
|
||||
}
|
||||
ss_rtcp->recvmsgnum = -1;
|
||||
ss_rtcp->chnum = chnum_rtcp;
|
||||
}
|
||||
@ -1032,8 +1080,9 @@ static int start_client(const char *remote_address, int port, const unsigned cha
|
||||
|
||||
refresh_channel(ss, 0, 600);
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
elems[i + 1] = ss_rtcp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1044,14 +1093,16 @@ static int start_c2c(const char *remote_address, int port, const unsigned char *
|
||||
app_ur_session *ss1 = create_new_ss();
|
||||
app_ur_session *ss1_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
ss1_rtcp = create_new_ss();
|
||||
}
|
||||
|
||||
app_ur_session *ss2 = create_new_ss();
|
||||
app_ur_session *ss2_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
ss2_rtcp = create_new_ss();
|
||||
}
|
||||
|
||||
app_ur_conn_info clnet_info_probe; /* for load balancing probe */
|
||||
memset(&clnet_info_probe, 0, sizeof(clnet_info_probe));
|
||||
@ -1060,14 +1111,16 @@ static int start_c2c(const char *remote_address, int port, const unsigned char *
|
||||
app_ur_conn_info *clnet_info1 = &(ss1->pinfo);
|
||||
app_ur_conn_info *clnet_info1_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
clnet_info1_rtcp = &(ss1_rtcp->pinfo);
|
||||
}
|
||||
|
||||
app_ur_conn_info *clnet_info2 = &(ss2->pinfo);
|
||||
app_ur_conn_info *clnet_info2_rtcp = NULL;
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
clnet_info2_rtcp = &(ss2_rtcp->pinfo);
|
||||
}
|
||||
|
||||
uint16_t chnum1 = 0;
|
||||
uint16_t chnum1_rtcp = 0;
|
||||
@ -1087,13 +1140,15 @@ static int start_c2c(const char *remote_address, int port, const unsigned char *
|
||||
|
||||
socket_set_nonblocking(clnet_info1->fd);
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
socket_set_nonblocking(clnet_info1_rtcp->fd);
|
||||
}
|
||||
|
||||
socket_set_nonblocking(clnet_info2->fd);
|
||||
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
socket_set_nonblocking(clnet_info2_rtcp->fd);
|
||||
}
|
||||
|
||||
struct event *ev1 = event_new(client_event_base, clnet_info1->fd, EV_READ | EV_PERSIST, client_input_handler, ss1);
|
||||
|
||||
@ -1132,8 +1187,9 @@ static int start_c2c(const char *remote_address, int port, const unsigned char *
|
||||
|
||||
ss1_rtcp->input_ev = ev1_rtcp;
|
||||
ss1_rtcp->tot_msgnum = ss1->tot_msgnum;
|
||||
if (ss1_rtcp->tot_msgnum < 1)
|
||||
if (ss1_rtcp->tot_msgnum < 1) {
|
||||
ss1_rtcp->tot_msgnum = 1;
|
||||
}
|
||||
ss1_rtcp->recvmsgnum = -1;
|
||||
ss1_rtcp->chnum = chnum1_rtcp;
|
||||
}
|
||||
@ -1155,11 +1211,13 @@ static int start_c2c(const char *remote_address, int port, const unsigned char *
|
||||
}
|
||||
|
||||
elems[i++] = ss1;
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
elems[i++] = ss1_rtcp;
|
||||
}
|
||||
elems[i++] = ss2;
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
elems[i++] = ss2_rtcp;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -1169,8 +1227,9 @@ static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt) {
|
||||
stun_buffer message;
|
||||
app_ur_conn_info *clnet_info = &(elem->pinfo);
|
||||
|
||||
if (clnet_info->is_peer)
|
||||
if (clnet_info->is_peer) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!method || (method == STUN_METHOD_REFRESH)) {
|
||||
stun_init_request(STUN_METHOD_REFRESH, &message);
|
||||
@ -1191,10 +1250,12 @@ static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt) {
|
||||
}
|
||||
|
||||
add_origin(&message);
|
||||
if (add_integrity(clnet_info, &message) < 0)
|
||||
if (add_integrity(clnet_info, &message) < 0) {
|
||||
return -1;
|
||||
if (use_fingerprints)
|
||||
}
|
||||
if (use_fingerprints) {
|
||||
stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len));
|
||||
}
|
||||
send_buffer(clnet_info, &message, 0, 0);
|
||||
}
|
||||
|
||||
@ -1205,10 +1266,12 @@ static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt) {
|
||||
stun_init_request(STUN_METHOD_CREATE_PERMISSION, &message);
|
||||
stun_attr_add_addr(&message, STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &(elem->pinfo.peer_addr));
|
||||
add_origin(&message);
|
||||
if (add_integrity(clnet_info, &message) < 0)
|
||||
if (add_integrity(clnet_info, &message) < 0) {
|
||||
return -1;
|
||||
if (use_fingerprints)
|
||||
}
|
||||
if (use_fingerprints) {
|
||||
stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len));
|
||||
}
|
||||
send_buffer(&(elem->pinfo), &message, 0, 0);
|
||||
}
|
||||
}
|
||||
@ -1217,10 +1280,12 @@ static int refresh_channel(app_ur_session *elem, uint16_t method, uint32_t lt) {
|
||||
if (STUN_VALID_CHANNEL(elem->chnum)) {
|
||||
stun_set_channel_bind_request(&message, &(elem->pinfo.peer_addr), elem->chnum);
|
||||
add_origin(&message);
|
||||
if (add_integrity(clnet_info, &message) < 0)
|
||||
if (add_integrity(clnet_info, &message) < 0) {
|
||||
return -1;
|
||||
if (use_fingerprints)
|
||||
}
|
||||
if (use_fingerprints) {
|
||||
stun_attr_add_fingerprint_str(message.buf, (size_t *)&(message.len));
|
||||
}
|
||||
send_buffer(&(elem->pinfo), &message, 1, 0);
|
||||
}
|
||||
}
|
||||
@ -1237,15 +1302,17 @@ static inline int client_timer_handler(app_ur_session *elem, int *done) {
|
||||
refresh_channel(elem, 0, 600);
|
||||
}
|
||||
|
||||
if (hang_on && elem->completed)
|
||||
if (hang_on && elem->completed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int max_num = 50;
|
||||
int cur_num = 0;
|
||||
|
||||
while (!turn_time_before(current_mstime, elem->to_send_timems)) {
|
||||
if (cur_num++ >= max_num)
|
||||
if (cur_num++ >= max_num) {
|
||||
break;
|
||||
}
|
||||
if (elem->wmsgnum >= elem->tot_msgnum) {
|
||||
if (!turn_time_before(current_mstime, elem->finished_time) || (tot_recv_messages >= tot_messages)) {
|
||||
/*
|
||||
@ -1292,9 +1359,8 @@ static void timer_handler(evutil_socket_t fd, short event, void *arg) {
|
||||
__turn_getMSTime();
|
||||
|
||||
if (start_full_timer) {
|
||||
int i = 0;
|
||||
int done = 0;
|
||||
for (i = 0; i < total_clients; ++i) {
|
||||
for (int i = 0; i < total_clients; ++i) {
|
||||
if (elems[i]) {
|
||||
int finished = client_timer_handler(elems[i], &done);
|
||||
if (finished) {
|
||||
@ -1303,7 +1369,7 @@ static void timer_handler(evutil_socket_t fd, short event, void *arg) {
|
||||
}
|
||||
}
|
||||
if (done > 5 && (dos || random_disconnect)) {
|
||||
for (i = 0; i < total_clients; ++i) {
|
||||
for (int i = 0; i < total_clients; ++i) {
|
||||
if (elems[i]) {
|
||||
socket_closesocket(elems[i]->pinfo.fd);
|
||||
elems[i]->pinfo.fd = -1;
|
||||
@ -1316,21 +1382,25 @@ static void timer_handler(evutil_socket_t fd, short event, void *arg) {
|
||||
void start_mclient(const char *remote_address, int port, const unsigned char *ifname, const char *local_address,
|
||||
int messagenumber, int mclient) {
|
||||
|
||||
if (mclient < 1)
|
||||
if (mclient < 1) {
|
||||
mclient = 1;
|
||||
}
|
||||
|
||||
total_clients = mclient;
|
||||
|
||||
if (c2c) {
|
||||
// mclient must be a multiple of 4:
|
||||
if (!no_rtcp)
|
||||
if (!no_rtcp) {
|
||||
mclient += ((4 - (mclient & 0x00000003)) & 0x00000003);
|
||||
else if (mclient & 0x1)
|
||||
} else if (mclient & 0x1) {
|
||||
++mclient;
|
||||
}
|
||||
} else {
|
||||
if (!no_rtcp)
|
||||
if (mclient & 0x1)
|
||||
if (!no_rtcp) {
|
||||
if (mclient & 0x1) {
|
||||
++mclient;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
elems = (app_ur_session **)malloc(sizeof(app_ur_session) * ((mclient * 2) + 1) + sizeof(void *));
|
||||
@ -1342,51 +1412,57 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
|
||||
client_event_base = turn_event_base_new();
|
||||
|
||||
int i = 0;
|
||||
int tot_clients = 0;
|
||||
|
||||
if (c2c) {
|
||||
if (!no_rtcp)
|
||||
for (i = 0; i < (mclient >> 2); i++) {
|
||||
if (!dos)
|
||||
if (!no_rtcp) {
|
||||
for (int i = 0; i < (mclient >> 2); i++) {
|
||||
if (!dos) {
|
||||
usleep(SLEEP_INTERVAL);
|
||||
}
|
||||
if (start_c2c(remote_address, port, ifname, local_address, messagenumber, i << 2) < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
tot_clients += 4;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < (mclient >> 1); i++) {
|
||||
if (!dos)
|
||||
} else {
|
||||
for (int i = 0; i < (mclient >> 1); i++) {
|
||||
if (!dos) {
|
||||
usleep(SLEEP_INTERVAL);
|
||||
}
|
||||
if (start_c2c(remote_address, port, ifname, local_address, messagenumber, i << 1) < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
tot_clients += 2;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (!no_rtcp)
|
||||
for (i = 0; i < (mclient >> 1); i++) {
|
||||
if (!dos)
|
||||
if (!no_rtcp) {
|
||||
for (int i = 0; i < (mclient >> 1); i++) {
|
||||
if (!dos) {
|
||||
usleep(SLEEP_INTERVAL);
|
||||
}
|
||||
if (start_client(remote_address, port, ifname, local_address, messagenumber, i << 1) < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
tot_clients += 2;
|
||||
}
|
||||
else
|
||||
for (i = 0; i < mclient; i++) {
|
||||
if (!dos)
|
||||
} else {
|
||||
for (int i = 0; i < mclient; i++) {
|
||||
if (!dos) {
|
||||
usleep(SLEEP_INTERVAL);
|
||||
}
|
||||
if (start_client(remote_address, port, ifname, local_address, messagenumber, i) < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
tot_clients++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (dos)
|
||||
if (dos) {
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
total_clients = tot_clients;
|
||||
|
||||
@ -1400,7 +1476,7 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
|
||||
evtimer_add(ev, &tv);
|
||||
|
||||
for (i = 0; i < total_clients; i++) {
|
||||
for (int i = 0; i < total_clients; i++) {
|
||||
|
||||
if (is_TCP_relay()) {
|
||||
if (passive_tcp) {
|
||||
@ -1409,8 +1485,7 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
socket_connect(elems[i]->pinfo.fd, &(elems[i]->pinfo.remote_addr), &connect_err);
|
||||
}
|
||||
} else {
|
||||
int j = 0;
|
||||
for (j = i + 1; j < total_clients; j++) {
|
||||
for (int j = i + 1; j < total_clients; j++) {
|
||||
if (turn_tcp_connect(clnet_verbose, &(elems[i]->pinfo), &(elems[j]->pinfo.relay_addr)) < 0) {
|
||||
exit(-1);
|
||||
}
|
||||
@ -1429,22 +1504,21 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
if (is_TCP_relay()) {
|
||||
uint64_t connect_wait_start_time = current_time;
|
||||
while (1) {
|
||||
int i = 0;
|
||||
int completed = 0;
|
||||
if (passive_tcp) {
|
||||
for (i = 0; i < total_clients; ++i) {
|
||||
for (int i = 0; i < total_clients; ++i) {
|
||||
if (elems[i]->pinfo.is_peer) {
|
||||
completed += 1;
|
||||
} else if (elems[i]->pinfo.tcp_conn_number > 0 && elems[i]->pinfo.tcp_conn[0]->tcp_data_bound) {
|
||||
completed += elems[i]->pinfo.tcp_conn_number;
|
||||
}
|
||||
}
|
||||
if (completed >= total_clients)
|
||||
if (completed >= total_clients) {
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < total_clients; ++i) {
|
||||
int j = 0;
|
||||
for (j = 0; j < (int)elems[i]->pinfo.tcp_conn_number; j++) {
|
||||
for (int i = 0; i < total_clients; ++i) {
|
||||
for (int j = 0; j < (int)elems[i]->pinfo.tcp_conn_number; j++) {
|
||||
if (elems[i]->pinfo.tcp_conn[j]->tcp_data_bound) {
|
||||
completed++;
|
||||
}
|
||||
@ -1466,15 +1540,15 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
__turn_getMSTime();
|
||||
stime = current_time;
|
||||
|
||||
for (i = 0; i < total_clients; i++) {
|
||||
for (int i = 0; i < total_clients; i++) {
|
||||
elems[i]->to_send_timems = current_mstime + 1000 + ((uint32_t)turn_random()) % 5000;
|
||||
}
|
||||
|
||||
tot_messages = elems[0]->tot_msgnum * total_clients;
|
||||
|
||||
start_full_timer = 1;
|
||||
start_full_timer = true;
|
||||
|
||||
while (1) {
|
||||
while (true) {
|
||||
|
||||
run_events(1);
|
||||
|
||||
@ -1488,7 +1562,7 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
"%s: msz=%d, tot_send_msgs=%lu, tot_recv_msgs=%lu, tot_send_bytes ~ %llu, tot_recv_bytes ~ %llu\n",
|
||||
__FUNCTION__, msz, (unsigned long)tot_send_messages, (unsigned long)tot_recv_messages,
|
||||
(unsigned long long)tot_send_bytes, (unsigned long long)tot_recv_bytes);
|
||||
show_statistics = 0;
|
||||
show_statistics = false;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1498,11 +1572,13 @@ void start_mclient(const char *remote_address, int port, const unsigned char *if
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%s: tot_send_bytes ~ %lu, tot_recv_bytes ~ %lu\n", __FUNCTION__,
|
||||
(unsigned long)tot_send_bytes, (unsigned long)tot_recv_bytes);
|
||||
|
||||
if (client_event_base)
|
||||
if (client_event_base) {
|
||||
event_base_free(client_event_base);
|
||||
}
|
||||
|
||||
if (tot_send_messages < tot_recv_messages)
|
||||
if (tot_send_messages < tot_recv_messages) {
|
||||
tot_recv_messages = tot_send_messages;
|
||||
}
|
||||
|
||||
total_loss = tot_send_messages - tot_recv_messages;
|
||||
|
||||
@ -1547,8 +1623,9 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) {
|
||||
while (!random_lifetime) {
|
||||
random_lifetime = turn_random();
|
||||
}
|
||||
if (random_lifetime < 0)
|
||||
if (random_lifetime < 0) {
|
||||
random_lifetime = -random_lifetime;
|
||||
}
|
||||
random_lifetime = random_lifetime % halflifetime;
|
||||
otoken.enc_block.lifetime = (uint32_t)(halflifetime + random_lifetime);
|
||||
otoken.enc_block.timestamp = ((uint64_t)turn_time()) << 16;
|
||||
@ -1562,19 +1639,19 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) {
|
||||
otoken.enc_block.key_length = 20;
|
||||
}
|
||||
RAND_bytes((unsigned char *)(otoken.enc_block.mac_key), otoken.enc_block.key_length);
|
||||
if (encode_oauth_token(clnet_info->server_name, &etoken, &(okey_array[cok]), &otoken, nonce) < 0) {
|
||||
if (!encode_oauth_token(clnet_info->server_name, &etoken, &(okey_array[cok]), &otoken, nonce)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot encode token\n");
|
||||
return -1;
|
||||
}
|
||||
stun_attr_add_str(message->buf, (size_t *)&(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN,
|
||||
stun_attr_add_str(message->buf, &(message->len), STUN_ATTRIBUTE_OAUTH_ACCESS_TOKEN,
|
||||
(const uint8_t *)etoken.token, (int)etoken.size);
|
||||
|
||||
memcpy(clnet_info->key, otoken.enc_block.mac_key, otoken.enc_block.key_length);
|
||||
clnet_info->key_set = 1;
|
||||
clnet_info->key_set = true;
|
||||
}
|
||||
|
||||
if (stun_attr_add_integrity_by_key_str(message->buf, (size_t *)&(message->len), (uint8_t *)okey_array[cok].kid,
|
||||
clnet_info->realm, clnet_info->key, clnet_info->nonce, shatype) < 0) {
|
||||
if (!stun_attr_add_integrity_by_key_str(message->buf, &(message->len), (uint8_t *)okey_array[cok].kid,
|
||||
clnet_info->realm, clnet_info->key, clnet_info->nonce, shatype)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot add integrity to the message\n");
|
||||
return -1;
|
||||
}
|
||||
@ -1582,15 +1659,15 @@ int add_integrity(app_ur_conn_info *clnet_info, stun_buffer *message) {
|
||||
// self-test:
|
||||
{
|
||||
password_t pwd;
|
||||
if (stun_check_message_integrity_by_key_str(get_turn_credentials_type(), message->buf, (size_t)(message->len),
|
||||
if (stun_check_message_integrity_by_key_str(get_turn_credentials_type(), message->buf, message->len,
|
||||
clnet_info->key, pwd, shatype) < 1) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, " Self-test of integrity does not comple correctly !\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (stun_attr_add_integrity_by_user_str(message->buf, (size_t *)&(message->len), g_uname, clnet_info->realm,
|
||||
g_upwd, clnet_info->nonce, shatype) < 0) {
|
||||
if (!stun_attr_add_integrity_by_user_str(message->buf, (size_t *)&(message->len), g_uname, clnet_info->realm,
|
||||
g_upwd, clnet_info->nonce, shatype)) {
|
||||
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, " Cannot add integrity to the message\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -31,12 +31,9 @@
|
||||
#ifndef __UCLIENT_ECHO__
|
||||
#define __UCLIENT_ECHO__
|
||||
|
||||
#include "ns_turn_utils.h"
|
||||
#include "session.h"
|
||||
#include "stun_buffer.h"
|
||||
|
||||
#include "ns_turn_openssl.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -47,42 +44,42 @@ extern "C" {
|
||||
#define STARTING_TCP_RELAY_TIME (30)
|
||||
|
||||
extern int clmessage_length;
|
||||
extern int do_not_use_channel;
|
||||
extern bool do_not_use_channel;
|
||||
extern int clnet_verbose;
|
||||
extern int use_tcp;
|
||||
extern int use_sctp;
|
||||
extern int use_secure;
|
||||
extern bool use_tcp;
|
||||
extern bool use_sctp;
|
||||
extern bool use_secure;
|
||||
extern char cert_file[1025];
|
||||
extern char pkey_file[1025];
|
||||
extern int hang_on;
|
||||
extern int c2c;
|
||||
extern bool hang_on;
|
||||
extern bool c2c;
|
||||
extern ioa_addr peer_addr;
|
||||
extern int no_rtcp;
|
||||
extern bool no_rtcp;
|
||||
extern int default_address_family;
|
||||
extern int dont_fragment;
|
||||
extern bool dont_fragment;
|
||||
extern uint8_t g_uname[STUN_MAX_USERNAME_SIZE + 1];
|
||||
extern password_t g_upwd;
|
||||
extern char g_auth_secret[1025];
|
||||
extern int g_use_auth_secret_with_timestamp;
|
||||
extern int use_fingerprints;
|
||||
extern bool g_use_auth_secret_with_timestamp;
|
||||
extern bool use_fingerprints;
|
||||
extern SSL_CTX *root_tls_ctx[32];
|
||||
extern int root_tls_ctx_num;
|
||||
extern int RTP_PACKET_INTERVAL;
|
||||
extern uint8_t relay_transport;
|
||||
extern unsigned char client_ifname[1025];
|
||||
extern struct event_base *client_event_base;
|
||||
extern int passive_tcp;
|
||||
extern int mandatory_channel_padding;
|
||||
extern int negative_test;
|
||||
extern int negative_protocol_test;
|
||||
extern int dos;
|
||||
extern int random_disconnect;
|
||||
extern bool passive_tcp;
|
||||
extern bool mandatory_channel_padding;
|
||||
extern bool negative_test;
|
||||
extern bool negative_protocol_test;
|
||||
extern bool dos;
|
||||
extern bool random_disconnect;
|
||||
extern SHATYPE shatype;
|
||||
extern int mobility;
|
||||
extern int no_permissions;
|
||||
extern int extra_requests;
|
||||
extern bool mobility;
|
||||
extern bool no_permissions;
|
||||
extern bool extra_requests;
|
||||
extern band_limit_t bps;
|
||||
extern int dual_allocation;
|
||||
extern bool dual_allocation;
|
||||
|
||||
extern char origin[STUN_MAX_ORIGIN_SIZE + 1];
|
||||
|
||||
@ -97,8 +94,8 @@ extern oauth_key okey_array[3];
|
||||
void start_mclient(const char *remote_address, int port, const unsigned char *ifname, const char *local_address,
|
||||
int messagenumber, int mclient);
|
||||
|
||||
int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int data_connection, app_tcp_conn_info *atc);
|
||||
int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, int sync, int data_connection,
|
||||
int send_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, bool data_connection, app_tcp_conn_info *atc);
|
||||
int recv_buffer(app_ur_conn_info *clnet_info, stun_buffer *message, bool sync, bool data_connection,
|
||||
app_tcp_conn_info *atc, stun_buffer *request_message);
|
||||
|
||||
void client_input_handler(evutil_socket_t fd, short what, void *arg);
|
||||
|
||||
@ -155,8 +155,9 @@ public:
|
||||
*/
|
||||
const uint8_t *getRawBuffer(size_t &sz) const {
|
||||
int len = stun_attr_get_len(_sar);
|
||||
if (len < 0)
|
||||
if (len < 0) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
sz = (size_t)len;
|
||||
const uint8_t *value = stun_attr_get_value(_sar);
|
||||
return value;
|
||||
@ -189,24 +190,28 @@ public:
|
||||
}
|
||||
size_t sz = 0;
|
||||
const uint8_t *ptr = iter.getRawBuffer(sz);
|
||||
if (sz >= 0xFFFF)
|
||||
if (sz >= 0xFFFF) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
int at = iter.getType();
|
||||
if (at < 0)
|
||||
if (at < 0) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
_attr_type = (uint16_t)at;
|
||||
_sz = sz;
|
||||
_value = (uint8_t *)malloc(_sz);
|
||||
if (ptr)
|
||||
if (ptr) {
|
||||
memcpy(_value, ptr, _sz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Destructor
|
||||
*/
|
||||
virtual ~StunAttr() {
|
||||
if (_value)
|
||||
if (_value) {
|
||||
free(_value);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -221,14 +226,17 @@ public:
|
||||
* Set raw data value
|
||||
*/
|
||||
void setRawValue(uint8_t *value, size_t sz) {
|
||||
if (sz > 0xFFFF)
|
||||
if (sz > 0xFFFF) {
|
||||
throw WrongStunAttrFormatException();
|
||||
if (_value)
|
||||
}
|
||||
if (_value) {
|
||||
free(_value);
|
||||
}
|
||||
_sz = sz;
|
||||
_value = (uint8_t *)malloc(_sz);
|
||||
if (value)
|
||||
if (value) {
|
||||
memcpy(_value, value, _sz);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -245,8 +253,9 @@ public:
|
||||
* Add attribute to a message
|
||||
*/
|
||||
template <class T> int addToMsg(T &msg) {
|
||||
if (!_attr_type)
|
||||
if (!_attr_type) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
uint8_t *buffer = msg.getRawBuffer();
|
||||
if (buffer) {
|
||||
size_t sz = msg.getSize();
|
||||
@ -265,9 +274,10 @@ protected:
|
||||
*/
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
if (buffer) {
|
||||
if (!_value)
|
||||
if (!_value) {
|
||||
throw WrongStunAttrFormatException();
|
||||
if (stun_attr_add_str(buffer, &sz, _attr_type, _value, _sz) < 0) {
|
||||
}
|
||||
if (!stun_attr_add_str(buffer, &sz, _attr_type, _value, _sz)) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
return 0;
|
||||
@ -294,18 +304,20 @@ public:
|
||||
StunAttrChannelNumber() : _cn(0) { setType(STUN_ATTRIBUTE_CHANNEL_NUMBER); }
|
||||
StunAttrChannelNumber(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
_cn = stun_attr_get_channel_number(getSar(iter));
|
||||
if (!_cn)
|
||||
if (!_cn) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
}
|
||||
virtual ~StunAttrChannelNumber() {}
|
||||
uint16_t getChannelNumber() const { return _cn; }
|
||||
void setChannelNumber(uint16_t cn) { _cn = cn; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_channel_number_str(buffer, &sz, _cn); }
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_channel_number_str(buffer, &sz, _cn); }
|
||||
|
||||
private:
|
||||
uint16_t _cn;
|
||||
@ -319,8 +331,9 @@ public:
|
||||
StunAttrEvenPort() : _ep(0) { setType(STUN_ATTRIBUTE_EVEN_PORT); }
|
||||
StunAttrEvenPort(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
_ep = stun_attr_get_even_port(getSar(iter));
|
||||
}
|
||||
virtual ~StunAttrEvenPort() {}
|
||||
@ -328,7 +341,7 @@ public:
|
||||
void setEvenPort(uint8_t ep) { _ep = ep; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_EVEN_PORT, &_ep, 1);
|
||||
}
|
||||
|
||||
@ -344,8 +357,9 @@ public:
|
||||
StunAttrReservationToken() : _rt(0) { setType(STUN_ATTRIBUTE_RESERVATION_TOKEN); }
|
||||
StunAttrReservationToken(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
_rt = stun_attr_get_reservation_token_value(getSar(iter));
|
||||
}
|
||||
virtual ~StunAttrReservationToken() {}
|
||||
@ -353,7 +367,7 @@ public:
|
||||
void setReservationToken(uint64_t rt) { _rt = rt; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
uint64_t reservation_token = ioa_ntoh64(_rt);
|
||||
return stun_attr_add_str(buffer, &sz, STUN_ATTRIBUTE_RESERVATION_TOKEN, (uint8_t *)(&reservation_token), 8);
|
||||
}
|
||||
@ -373,11 +387,12 @@ public:
|
||||
}
|
||||
StunAttrAddr(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
size_t sz = 0;
|
||||
const uint8_t *buf = iter.getRawBuffer(sz);
|
||||
if (stun_attr_get_addr_str(buf, sz, getSar(iter), &_addr, NULL) < 0) {
|
||||
if (!stun_attr_get_addr_str(buf, sz, getSar(iter), &_addr, NULL)) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
}
|
||||
@ -386,7 +401,7 @@ public:
|
||||
void setAddr(ioa_addr &addr) { addr_cpy(&_addr, &addr); }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
return stun_attr_add_addr_str(buffer, &sz, getType(), &_addr);
|
||||
}
|
||||
|
||||
@ -399,40 +414,31 @@ private:
|
||||
*/
|
||||
class StunAttrChangeRequest : public StunAttr {
|
||||
public:
|
||||
StunAttrChangeRequest() : _changeIp(0), _changePort(0) { setType(STUN_ATTRIBUTE_CHANGE_REQUEST); }
|
||||
StunAttrChangeRequest() : _changeIp(false), _changePort(false) { setType(STUN_ATTRIBUTE_CHANGE_REQUEST); }
|
||||
StunAttrChangeRequest(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
|
||||
if (stun_attr_get_change_request_str(getSar(iter), &_changeIp, &_changePort) < 0) {
|
||||
if (!stun_attr_get_change_request_str(getSar(iter), &_changeIp, &_changePort)) {
|
||||
throw WrongStunAttrFormatException();
|
||||
}
|
||||
}
|
||||
virtual ~StunAttrChangeRequest() {}
|
||||
bool getChangeIp() const { return _changeIp; }
|
||||
void setChangeIp(bool ci) {
|
||||
if (ci)
|
||||
_changeIp = 1;
|
||||
else
|
||||
_changeIp = 0;
|
||||
}
|
||||
void setChangeIp(bool ci) { _changeIp = ci; }
|
||||
bool getChangePort() const { return _changePort; }
|
||||
void setChangePort(bool cp) {
|
||||
if (cp)
|
||||
_changePort = 1;
|
||||
else
|
||||
_changePort = 0;
|
||||
}
|
||||
void setChangePort(bool cp) { _changePort = cp; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) {
|
||||
return stun_attr_add_change_request_str(buffer, &sz, _changeIp, _changePort);
|
||||
}
|
||||
|
||||
private:
|
||||
int _changeIp;
|
||||
int _changePort;
|
||||
bool _changeIp;
|
||||
bool _changePort;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -443,8 +449,9 @@ public:
|
||||
StunAttrResponsePort() : _rp(0) { setType(STUN_ATTRIBUTE_RESPONSE_PORT); }
|
||||
StunAttrResponsePort(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
|
||||
int rp = stun_attr_get_response_port_str(getSar(iter));
|
||||
if (rp < 0) {
|
||||
@ -457,7 +464,7 @@ public:
|
||||
void setResponsePort(uint16_t p) { _rp = p; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_response_port_str(buffer, &sz, _rp); }
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_response_port_str(buffer, &sz, _rp); }
|
||||
|
||||
private:
|
||||
uint16_t _rp;
|
||||
@ -471,8 +478,9 @@ public:
|
||||
StunAttrPadding() : _p(0) { setType(STUN_ATTRIBUTE_PADDING); }
|
||||
StunAttrPadding(const StunAttrIterator &iter) : StunAttr(iter) {
|
||||
|
||||
if (iter.eof())
|
||||
if (iter.eof()) {
|
||||
throw EndOfStunMsgException();
|
||||
}
|
||||
|
||||
int p = stun_attr_get_padding_len_str(getSar(iter));
|
||||
if (p < 0) {
|
||||
@ -488,7 +496,7 @@ public:
|
||||
void setPadding(uint16_t p) { _p = p; }
|
||||
|
||||
protected:
|
||||
virtual int addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_padding_str(buffer, &sz, _p); }
|
||||
virtual bool addToBuffer(uint8_t *buffer, size_t &sz) { return stun_attr_add_padding_str(buffer, &sz, _p); }
|
||||
|
||||
private:
|
||||
uint16_t _p;
|
||||
@ -550,8 +558,9 @@ public:
|
||||
* Set message size
|
||||
*/
|
||||
void setSize(size_t sz) {
|
||||
if (sz > _allocated_sz)
|
||||
if (sz > _allocated_sz) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
_sz = sz;
|
||||
}
|
||||
|
||||
@ -579,7 +588,7 @@ public:
|
||||
* Check if the raw buffer is a challenge response (the one with 401 error and realm and nonce values).
|
||||
*/
|
||||
static bool isChallengeResponse(const uint8_t *buf, size_t sz, int &err_code, uint8_t *err_msg, size_t err_msg_size,
|
||||
uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth) {
|
||||
uint8_t *realm, uint8_t *nonce, uint8_t *server_name, bool *oauth) {
|
||||
return stun_is_challenge_response_str(buf, sz, &err_code, err_msg, err_msg_size, realm, nonce, server_name, oauth);
|
||||
}
|
||||
|
||||
@ -592,11 +601,13 @@ public:
|
||||
* Check if the fingerprint is present.
|
||||
*/
|
||||
static bool isFingerprintPresent(uint8_t *buffer, size_t sz) {
|
||||
if (!stun_is_command_message_str(buffer, sz))
|
||||
if (!stun_is_command_message_str(buffer, sz)) {
|
||||
return false;
|
||||
}
|
||||
stun_attr_ref sar = stun_attr_get_first_by_type_str(buffer, sz, STUN_ATTRIBUTE_FINGERPRINT);
|
||||
if (!sar)
|
||||
if (!sar) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -617,8 +628,9 @@ public:
|
||||
* Get transaction ID
|
||||
*/
|
||||
virtual stun_tid getTid() const {
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
stun_tid tid;
|
||||
stun_tid_from_message_str(_buffer, _sz, &tid);
|
||||
return tid;
|
||||
@ -628,8 +640,9 @@ public:
|
||||
* Set transaction ID
|
||||
*/
|
||||
virtual void setTid(stun_tid &tid) {
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
stun_tid_message_cpy(_buffer, &tid);
|
||||
}
|
||||
|
||||
@ -637,8 +650,9 @@ public:
|
||||
* Add fingerprint to the message
|
||||
*/
|
||||
void addFingerprint() {
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
stun_attr_add_fingerprint_str(_buffer, &_sz);
|
||||
}
|
||||
|
||||
@ -646,8 +660,9 @@ public:
|
||||
* Check message integrity, in secure communications.
|
||||
*/
|
||||
bool checkMessageIntegrity(turn_credential_type ct, std::string &uname, std::string &realm, std::string &upwd) const {
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
uint8_t *suname = (uint8_t *)strdup(uname.c_str());
|
||||
uint8_t *srealm = (uint8_t *)strdup(realm.c_str());
|
||||
uint8_t *supwd = (uint8_t *)strdup(upwd.c_str());
|
||||
@ -664,8 +679,9 @@ public:
|
||||
*/
|
||||
void addLTMessageIntegrity(std::string &uname, std::string &realm, std::string &upwd, std::string &nonce) {
|
||||
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
|
||||
uint8_t *suname = (uint8_t *)strdup(uname.c_str());
|
||||
uint8_t *srealm = (uint8_t *)strdup(realm.c_str());
|
||||
@ -685,8 +701,9 @@ public:
|
||||
*/
|
||||
void addSTMessageIntegrity(std::string &uname, std::string &upwd) {
|
||||
|
||||
if (!_constructed || !isCommand())
|
||||
if (!_constructed || !isCommand()) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
|
||||
uint8_t *suname = (uint8_t *)strdup(uname.c_str());
|
||||
uint8_t *supwd = (uint8_t *)strdup(upwd.c_str());
|
||||
@ -766,8 +783,9 @@ protected:
|
||||
}
|
||||
|
||||
virtual bool check() {
|
||||
if (!_constructed)
|
||||
if (!_constructed) {
|
||||
return false;
|
||||
}
|
||||
if (!stun_is_request_str(_buffer, _sz)) {
|
||||
return false;
|
||||
}
|
||||
@ -876,7 +894,7 @@ public:
|
||||
*/
|
||||
void constructBindingResponse(stun_tid &tid, const ioa_addr &reflexive_addr, int error_code, const uint8_t *reason) {
|
||||
|
||||
stun_set_binding_response_str(_buffer, &_sz, &tid, &reflexive_addr, error_code, reason, 0, 0, 1);
|
||||
stun_set_binding_response_str(_buffer, &_sz, &tid, &reflexive_addr, error_code, reason, 0, false, true);
|
||||
}
|
||||
|
||||
bool isBindingResponse() const { return stun_is_binding_response_str(_buffer, _sz); }
|
||||
@ -911,8 +929,9 @@ protected:
|
||||
}
|
||||
|
||||
virtual bool check() {
|
||||
if (!_constructed)
|
||||
if (!_constructed) {
|
||||
return false;
|
||||
}
|
||||
if (!stun_is_success_response_str(_buffer, _sz)) {
|
||||
uint8_t errtxt[0xFFFF];
|
||||
int cerr = 0;
|
||||
@ -965,8 +984,9 @@ protected:
|
||||
}
|
||||
|
||||
virtual bool check() {
|
||||
if (!_constructed)
|
||||
if (!_constructed) {
|
||||
return false;
|
||||
}
|
||||
if (!stun_is_indication_str(_buffer, _sz)) {
|
||||
return false;
|
||||
}
|
||||
@ -990,16 +1010,18 @@ public:
|
||||
: StunMsg(buffer, total_sz, sz, constructed), _cn(0) {
|
||||
|
||||
if (constructed) {
|
||||
if (!stun_is_channel_message_str(buffer, &_sz, &_cn, 0)) {
|
||||
if (!stun_is_channel_message_str(buffer, &_sz, &_cn, false)) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
if (_sz > 0xFFFF || _sz < 4)
|
||||
if (_sz > 0xFFFF || _sz < 4) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
|
||||
_len = _sz - 4;
|
||||
} else {
|
||||
if (total_sz > 0xFFFF || total_sz < 4)
|
||||
if (total_sz > 0xFFFF || total_sz < 4) {
|
||||
throw WrongStunBufferFormatException();
|
||||
}
|
||||
|
||||
_len = 0;
|
||||
}
|
||||
@ -1027,10 +1049,11 @@ protected:
|
||||
}
|
||||
|
||||
virtual bool check() {
|
||||
if (!_constructed)
|
||||
if (!_constructed) {
|
||||
return false;
|
||||
}
|
||||
uint16_t cn = 0;
|
||||
if (!stun_is_channel_message_str(_buffer, &_sz, &cn, 0)) {
|
||||
if (!stun_is_channel_message_str(_buffer, &_sz, &cn, false)) {
|
||||
return false;
|
||||
}
|
||||
if (_cn != cn) {
|
||||
|
||||
@ -30,6 +30,12 @@
|
||||
|
||||
#include "ns_turn_ioaddr.h"
|
||||
|
||||
#include "ns_turn_defs.h" // for nswap16, nswap32, STRCPY
|
||||
|
||||
#include <stdio.h> // for snprintf, fprintf, stderr
|
||||
#include <stdlib.h> // for atoi, malloc, realloc, free
|
||||
#include <string.h> // for memcpy, strncpy, memset, NULL, memcmp, strstr
|
||||
|
||||
#if defined(__unix__) || defined(unix) || defined(__APPLE__)
|
||||
#include <netdb.h>
|
||||
#endif
|
||||
@ -37,35 +43,40 @@
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
uint32_t get_ioa_addr_len(const ioa_addr *addr) {
|
||||
if (addr->ss.sa_family == AF_INET)
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
return sizeof(struct sockaddr_in);
|
||||
else if (addr->ss.sa_family == AF_INET6)
|
||||
} else if (addr->ss.sa_family == AF_INET6) {
|
||||
return sizeof(struct sockaddr_in6);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
void addr_set_any(ioa_addr *addr) {
|
||||
if (addr)
|
||||
if (addr) {
|
||||
memset(addr, 0, sizeof(ioa_addr));
|
||||
}
|
||||
}
|
||||
|
||||
int addr_any(const ioa_addr *addr) {
|
||||
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
return ((addr->s4.sin_addr.s_addr == 0) && (addr->s4.sin_port == 0));
|
||||
} else if (addr->ss.sa_family == AF_INET6) {
|
||||
if (addr->s6.sin6_port != 0)
|
||||
if (addr->s6.sin6_port != 0) {
|
||||
return 0;
|
||||
else {
|
||||
} else {
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(addr->s6.sin6_addr); i++)
|
||||
if (((const char *)&(addr->s6.sin6_addr))[i])
|
||||
for (i = 0; i < sizeof(addr->s6.sin6_addr); i++) {
|
||||
if (((const char *)&(addr->s6.sin6_addr))[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -73,16 +84,19 @@ int addr_any(const ioa_addr *addr) {
|
||||
}
|
||||
|
||||
int addr_any_no_port(const ioa_addr *addr) {
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
return (addr->s4.sin_addr.s_addr == 0);
|
||||
} else if (addr->ss.sa_family == AF_INET6) {
|
||||
size_t i;
|
||||
for (i = 0; i < sizeof(addr->s6.sin6_addr); i++)
|
||||
if (((const char *)(&(addr->s6.sin6_addr)))[i])
|
||||
for (i = 0; i < sizeof(addr->s6.sin6_addr); i++) {
|
||||
if (((const char *)(&(addr->s6.sin6_addr)))[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 1;
|
||||
@ -103,8 +117,9 @@ uint64_t hash_int64(uint64_t a) {
|
||||
}
|
||||
|
||||
uint32_t addr_hash(const ioa_addr *addr) {
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ret = 0;
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
@ -118,8 +133,9 @@ uint32_t addr_hash(const ioa_addr *addr) {
|
||||
}
|
||||
|
||||
uint32_t addr_hash_no_port(const ioa_addr *addr) {
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint32_t ret = 0;
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
@ -133,26 +149,30 @@ uint32_t addr_hash_no_port(const ioa_addr *addr) {
|
||||
}
|
||||
|
||||
void addr_cpy(ioa_addr *dst, const ioa_addr *src) {
|
||||
if (dst && src)
|
||||
if (dst && src) {
|
||||
memcpy(dst, src, sizeof(ioa_addr));
|
||||
}
|
||||
}
|
||||
|
||||
void addr_cpy4(ioa_addr *dst, const struct sockaddr_in *src) {
|
||||
if (src && dst)
|
||||
if (src && dst) {
|
||||
memcpy(dst, src, sizeof(struct sockaddr_in));
|
||||
}
|
||||
}
|
||||
|
||||
void addr_cpy6(ioa_addr *dst, const struct sockaddr_in6 *src) {
|
||||
if (src && dst)
|
||||
if (src && dst) {
|
||||
memcpy(dst, src, sizeof(struct sockaddr_in6));
|
||||
}
|
||||
}
|
||||
|
||||
int addr_eq(const ioa_addr *a1, const ioa_addr *a2) {
|
||||
|
||||
if (!a1)
|
||||
if (!a1) {
|
||||
return (!a2);
|
||||
else if (!a2)
|
||||
} else if (!a2) {
|
||||
return (!a1);
|
||||
}
|
||||
|
||||
if (a1->ss.sa_family == a2->ss.sa_family) {
|
||||
if (a1->ss.sa_family == AF_INET && a1->s4.sin_port == a2->s4.sin_port) {
|
||||
@ -171,10 +191,11 @@ int addr_eq(const ioa_addr *a1, const ioa_addr *a2) {
|
||||
|
||||
int addr_eq_no_port(const ioa_addr *a1, const ioa_addr *a2) {
|
||||
|
||||
if (!a1)
|
||||
if (!a1) {
|
||||
return (!a2);
|
||||
else if (!a2)
|
||||
} else if (!a2) {
|
||||
return (!a1);
|
||||
}
|
||||
|
||||
if (a1->ss.sa_family == a2->ss.sa_family) {
|
||||
if (a1->ss.sa_family == AF_INET) {
|
||||
@ -192,15 +213,17 @@ int addr_eq_no_port(const ioa_addr *a1, const ioa_addr *a2) {
|
||||
|
||||
int make_ioa_addr(const uint8_t *saddr0, int port, ioa_addr *addr) {
|
||||
|
||||
if (!saddr0 || !addr)
|
||||
if (!saddr0 || !addr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
char ssaddr[257];
|
||||
STRCPY(ssaddr, saddr0);
|
||||
|
||||
char *saddr = ssaddr;
|
||||
while (*saddr == ' ')
|
||||
while (*saddr == ' ') {
|
||||
++saddr;
|
||||
}
|
||||
|
||||
size_t len = strlen(saddr);
|
||||
while (len > 0) {
|
||||
@ -290,16 +313,18 @@ int make_ioa_addr(const uint8_t *saddr0, int port, ioa_addr *addr) {
|
||||
|
||||
static char *get_addr_string_and_port(char *s0, int *port) {
|
||||
char *s = s0;
|
||||
while (*s && (*s == ' '))
|
||||
while (*s && (*s == ' ')) {
|
||||
++s;
|
||||
}
|
||||
if (*s == '[') {
|
||||
++s;
|
||||
char *tail = strstr(s, "]");
|
||||
if (tail) {
|
||||
*tail = 0;
|
||||
++tail;
|
||||
while (*tail && (*tail == ' '))
|
||||
while (*tail && (*tail == ' ')) {
|
||||
++tail;
|
||||
}
|
||||
if (*tail == ':') {
|
||||
++tail;
|
||||
*port = atoi(tail);
|
||||
@ -325,16 +350,18 @@ static char *get_addr_string_and_port(char *s0, int *port) {
|
||||
}
|
||||
|
||||
int make_ioa_addr_from_full_string(const uint8_t *saddr, int default_port, ioa_addr *addr) {
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
int port = 0;
|
||||
char *s = strdup((const char *)saddr);
|
||||
char *sa = get_addr_string_and_port(s, &port);
|
||||
if (sa) {
|
||||
if (port < 1)
|
||||
if (port < 1) {
|
||||
port = default_port;
|
||||
}
|
||||
ret = make_ioa_addr((uint8_t *)sa, port, addr);
|
||||
}
|
||||
free(s);
|
||||
@ -349,16 +376,18 @@ int addr_to_string(const ioa_addr *addr, uint8_t *saddr) {
|
||||
|
||||
if (addr->ss.sa_family == AF_INET) {
|
||||
inet_ntop(AF_INET, &addr->s4.sin_addr, addrtmp, INET_ADDRSTRLEN);
|
||||
if (addr_get_port(addr) > 0)
|
||||
if (addr_get_port(addr) > 0) {
|
||||
snprintf((char *)saddr, MAX_IOA_ADDR_STRING, "%s:%d", addrtmp, addr_get_port(addr));
|
||||
else
|
||||
} else {
|
||||
strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING);
|
||||
}
|
||||
} else if (addr->ss.sa_family == AF_INET6) {
|
||||
inet_ntop(AF_INET6, &addr->s6.sin6_addr, addrtmp, INET6_ADDRSTRLEN);
|
||||
if (addr_get_port(addr) > 0)
|
||||
if (addr_get_port(addr) > 0) {
|
||||
snprintf((char *)saddr, MAX_IOA_ADDR_STRING, "[%s]:%d", addrtmp, addr_get_port(addr));
|
||||
else
|
||||
} else {
|
||||
strncpy((char *)saddr, addrtmp, MAX_IOA_ADDR_STRING);
|
||||
}
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@ -402,8 +431,9 @@ void addr_set_port(ioa_addr *addr, int port) {
|
||||
}
|
||||
|
||||
int addr_get_port(const ioa_addr *addr) {
|
||||
if (!addr)
|
||||
if (!addr) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (addr->s4.sin_family == AF_INET) {
|
||||
return nswap16(addr->s4.sin_port);
|
||||
@ -417,37 +447,42 @@ int addr_get_port(const ioa_addr *addr) {
|
||||
|
||||
void ioa_addr_range_set(ioa_addr_range *range, const ioa_addr *addr_min, const ioa_addr *addr_max) {
|
||||
if (range) {
|
||||
if (addr_min)
|
||||
if (addr_min) {
|
||||
addr_cpy(&(range->min), addr_min);
|
||||
else
|
||||
} else {
|
||||
addr_set_any(&(range->min));
|
||||
if (addr_max)
|
||||
}
|
||||
if (addr_max) {
|
||||
addr_cpy(&(range->max), addr_max);
|
||||
else
|
||||
} else {
|
||||
addr_set_any(&(range->max));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int addr_less_eq(const ioa_addr *addr1, const ioa_addr *addr2) {
|
||||
|
||||
if (!addr1)
|
||||
if (!addr1) {
|
||||
return 1;
|
||||
else if (!addr2)
|
||||
} else if (!addr2) {
|
||||
return 0;
|
||||
else {
|
||||
if (addr1->ss.sa_family != addr2->ss.sa_family)
|
||||
} else {
|
||||
if (addr1->ss.sa_family != addr2->ss.sa_family) {
|
||||
return (addr1->ss.sa_family < addr2->ss.sa_family);
|
||||
else if (addr1->ss.sa_family == AF_INET) {
|
||||
} else if (addr1->ss.sa_family == AF_INET) {
|
||||
return ((uint32_t)nswap32(addr1->s4.sin_addr.s_addr) <= (uint32_t)nswap32(addr2->s4.sin_addr.s_addr));
|
||||
} else if (addr1->ss.sa_family == AF_INET6) {
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if ((uint8_t)(((const char *)&(addr1->s6.sin6_addr))[i]) > (uint8_t)(((const char *)&(addr2->s6.sin6_addr))[i]))
|
||||
if ((uint8_t)(((const char *)&(addr1->s6.sin6_addr))[i]) >
|
||||
(uint8_t)(((const char *)&(addr2->s6.sin6_addr))[i])) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
} else
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -498,8 +533,9 @@ int ioa_addr_is_loopback(ioa_addr *addr) {
|
||||
if (u[15] == 1) {
|
||||
int i;
|
||||
for (i = 0; i < 15; ++i) {
|
||||
if (u[i])
|
||||
if (u[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@ -523,8 +559,9 @@ int ioa_addr_is_zero(ioa_addr *addr) {
|
||||
const uint8_t *u = ((const uint8_t *)&(addr->s6.sin6_addr));
|
||||
int i;
|
||||
for (i = 0; i <= 15; ++i) {
|
||||
if (u[i])
|
||||
if (u[i]) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -31,9 +31,12 @@
|
||||
#ifndef __LIB_TURN_MSG__
|
||||
#define __LIB_TURN_MSG__
|
||||
|
||||
#include "ns_turn_defs.h" // for turn_time_t
|
||||
#include "ns_turn_ioaddr.h"
|
||||
#include "ns_turn_msg_defs.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
@ -72,7 +75,7 @@ typedef const void *stun_attr_ref;
|
||||
|
||||
//////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_tid_equals(const stun_tid *id1, const stun_tid *id2);
|
||||
bool stun_tid_equals(const stun_tid *id1, const stun_tid *id2);
|
||||
void stun_tid_cpy(stun_tid *id_dst, const stun_tid *id_src);
|
||||
void stun_tid_generate(stun_tid *id);
|
||||
|
||||
@ -106,31 +109,31 @@ void stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, ui
|
||||
const uint8_t *reason, stun_tid *id);
|
||||
void old_stun_init_error_response_str(uint16_t method, uint8_t *buf, size_t *len, uint16_t error_code,
|
||||
const uint8_t *reason, stun_tid *id, uint32_t cookie);
|
||||
int stun_init_channel_message_str(uint16_t chnumber, uint8_t *buf, size_t *len, int length, int do_padding);
|
||||
bool stun_init_channel_message_str(uint16_t chnumber, uint8_t *buf, size_t *len, int length, bool do_padding);
|
||||
|
||||
int stun_is_command_message_str(const uint8_t *buf, size_t blen);
|
||||
int old_stun_is_command_message_str(const uint8_t *buf, size_t blen, uint32_t *cookie);
|
||||
int stun_is_command_message_full_check_str(const uint8_t *buf, size_t blen, int must_check_fingerprint,
|
||||
int *fingerprint_present);
|
||||
int stun_is_command_message_offset_str(const uint8_t *buf, size_t blen, int offset);
|
||||
int stun_is_request_str(const uint8_t *buf, size_t len);
|
||||
int stun_is_success_response_str(const uint8_t *buf, size_t len);
|
||||
int stun_is_error_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size);
|
||||
int stun_is_challenge_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size,
|
||||
uint8_t *realm, uint8_t *nonce, uint8_t *server_name, int *oauth);
|
||||
int stun_is_response_str(const uint8_t *buf, size_t len);
|
||||
int stun_is_indication_str(const uint8_t *buf, size_t len);
|
||||
bool stun_is_command_message_str(const uint8_t *buf, size_t blen);
|
||||
bool old_stun_is_command_message_str(const uint8_t *buf, size_t blen, uint32_t *cookie);
|
||||
bool stun_is_command_message_full_check_str(const uint8_t *buf, size_t blen, int must_check_fingerprint,
|
||||
int *fingerprint_present);
|
||||
bool stun_is_request_str(const uint8_t *buf, size_t len);
|
||||
bool stun_is_success_response_str(const uint8_t *buf, size_t len);
|
||||
bool stun_is_error_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg, size_t err_msg_size);
|
||||
bool stun_is_challenge_response_str(const uint8_t *buf, size_t len, int *err_code, uint8_t *err_msg,
|
||||
size_t err_msg_size, uint8_t *realm, uint8_t *nonce, uint8_t *server_name,
|
||||
bool *oauth);
|
||||
bool stun_is_response_str(const uint8_t *buf, size_t len);
|
||||
bool stun_is_indication_str(const uint8_t *buf, size_t len);
|
||||
uint16_t stun_get_method_str(const uint8_t *buf, size_t len);
|
||||
uint16_t stun_get_msg_type_str(const uint8_t *buf, size_t len);
|
||||
int stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t *chnumber, int mandatory_padding);
|
||||
int is_channel_msg_str(const uint8_t *buf, size_t blen);
|
||||
bool stun_is_channel_message_str(const uint8_t *buf, size_t *blen, uint16_t *chnumber, bool mandatory_padding);
|
||||
bool is_channel_msg_str(const uint8_t *buf, size_t blen);
|
||||
|
||||
void stun_set_binding_request_str(uint8_t *buf, size_t *len);
|
||||
int stun_set_binding_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *reflexive_addr,
|
||||
int error_code, const uint8_t *reason, uint32_t cookie, int old_stun,
|
||||
int no_stun_backward_compatibility);
|
||||
int stun_is_binding_request_str(const uint8_t *buf, size_t len, size_t offset);
|
||||
int stun_is_binding_response_str(const uint8_t *buf, size_t len);
|
||||
bool stun_set_binding_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *reflexive_addr,
|
||||
int error_code, const uint8_t *reason, uint32_t cookie, bool old_stun,
|
||||
bool no_stun_backward_compatibility);
|
||||
bool stun_is_binding_request_str(const uint8_t *buf, size_t len, size_t offset);
|
||||
bool stun_is_binding_response_str(const uint8_t *buf, size_t len);
|
||||
|
||||
void stun_tid_from_message_str(const uint8_t *buf, size_t len, stun_tid *id);
|
||||
void stun_tid_message_cpy(uint8_t *buf, const stun_tid *id);
|
||||
@ -140,7 +143,7 @@ int stun_get_command_message_len_str(const uint8_t *buf, size_t len);
|
||||
|
||||
const uint8_t *get_default_reason(int error_code);
|
||||
|
||||
int stun_attr_is_addr(stun_attr_ref attr);
|
||||
bool stun_attr_is_addr(stun_attr_ref attr);
|
||||
int stun_attr_get_type(stun_attr_ref attr);
|
||||
int stun_attr_get_len(stun_attr_ref attr);
|
||||
const uint8_t *stun_attr_get_value(stun_attr_ref attr);
|
||||
@ -151,25 +154,23 @@ uint64_t stun_attr_get_reservation_token_value(stun_attr_ref attr);
|
||||
stun_attr_ref stun_attr_get_first_by_type_str(const uint8_t *buf, size_t len, uint16_t attr_type);
|
||||
stun_attr_ref stun_attr_get_first_str(const uint8_t *buf, size_t len);
|
||||
stun_attr_ref stun_attr_get_next_str(const uint8_t *buf, size_t len, stun_attr_ref prev);
|
||||
int stun_attr_add_str(uint8_t *buf, size_t *len, uint16_t attr, const uint8_t *avalue, int alen);
|
||||
int stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr *ca);
|
||||
int stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr *ca,
|
||||
const ioa_addr *default_addr);
|
||||
int stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr *ca,
|
||||
const ioa_addr *default_addr);
|
||||
int stun_attr_add_channel_number_str(uint8_t *buf, size_t *len, uint16_t chnumber);
|
||||
int stun_attr_add_bandwidth_str(uint8_t *buf, size_t *len, band_limit_t bps);
|
||||
int stun_attr_add_address_error_code(uint8_t *buf, size_t *len, int requested_address_family, int error_code);
|
||||
/* return +1 if present, 0 if not, -1 if error: */
|
||||
int stun_attr_get_address_error_code(uint8_t *buf, size_t len, int *requested_address_family, int *error_code);
|
||||
bool stun_attr_add_str(uint8_t *buf, size_t *len, uint16_t attr, const uint8_t *avalue, int alen);
|
||||
bool stun_attr_add_addr_str(uint8_t *buf, size_t *len, uint16_t attr_type, const ioa_addr *ca);
|
||||
bool stun_attr_get_addr_str(const uint8_t *buf, size_t len, stun_attr_ref attr, ioa_addr *ca,
|
||||
const ioa_addr *default_addr);
|
||||
bool stun_attr_get_first_addr_str(const uint8_t *buf, size_t len, uint16_t attr_type, ioa_addr *ca,
|
||||
const ioa_addr *default_addr);
|
||||
bool stun_attr_add_channel_number_str(uint8_t *buf, size_t *len, uint16_t chnumber);
|
||||
bool stun_attr_add_bandwidth_str(uint8_t *buf, size_t *len, band_limit_t bps);
|
||||
bool stun_attr_add_address_error_code(uint8_t *buf, size_t *len, int requested_address_family, int error_code);
|
||||
uint16_t stun_attr_get_first_channel_number_str(const uint8_t *buf, size_t len);
|
||||
|
||||
int stun_set_allocate_request_str(uint8_t *buf, size_t *len, uint32_t lifetime, int af4, int af6, uint8_t transport,
|
||||
int mobile, const char *rt, int ep);
|
||||
int stun_set_allocate_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason,
|
||||
uint64_t reservation_token, char *mobile_id);
|
||||
bool stun_set_allocate_request_str(uint8_t *buf, size_t *len, uint32_t lifetime, bool af4, bool af6, uint8_t transport,
|
||||
bool mobile, const char *rt, int ep);
|
||||
bool stun_set_allocate_response_str(uint8_t *buf, size_t *len, stun_tid *tid, const ioa_addr *relayed_addr1,
|
||||
const ioa_addr *relayed_addr2, const ioa_addr *reflexive_addr, uint32_t lifetime,
|
||||
uint32_t max_lifetime, int error_code, const uint8_t *reason,
|
||||
uint64_t reservation_token, char *mobile_id);
|
||||
|
||||
uint16_t stun_set_channel_bind_request_str(uint8_t *buf, size_t *len, const ioa_addr *peer_addr,
|
||||
uint16_t channel_number);
|
||||
@ -178,9 +179,9 @@ void stun_set_channel_bind_response_str(uint8_t *buf, size_t *len, stun_tid *tid
|
||||
|
||||
int stun_get_requested_address_family(stun_attr_ref attr);
|
||||
|
||||
int stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len);
|
||||
bool stun_attr_add_fingerprint_str(uint8_t *buf, size_t *len);
|
||||
|
||||
int SASLprep(uint8_t *s);
|
||||
bool SASLprep(uint8_t *s);
|
||||
|
||||
#define print_bin(str, len, field) print_bin_func(str, len, field, __FUNCTION__)
|
||||
void print_bin_func(const char *name, size_t len, const void *s, const char *func);
|
||||
@ -192,14 +193,14 @@ int stun_check_message_integrity_by_key_str(turn_credential_type ct, uint8_t *bu
|
||||
password_t pwd, SHATYPE shatype);
|
||||
int stun_check_message_integrity_str(turn_credential_type ct, uint8_t *buf, size_t len, const uint8_t *uname,
|
||||
const uint8_t *realm, const uint8_t *upwd, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd,
|
||||
SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm,
|
||||
hmackey_t key, const uint8_t *nonce, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm,
|
||||
const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype);
|
||||
int stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd,
|
||||
SHATYPE shatype);
|
||||
bool stun_attr_add_integrity_str(turn_credential_type ct, uint8_t *buf, size_t *len, hmackey_t key, password_t pwd,
|
||||
SHATYPE shatype);
|
||||
bool stun_attr_add_integrity_by_key_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm,
|
||||
hmackey_t key, const uint8_t *nonce, SHATYPE shatype);
|
||||
bool stun_attr_add_integrity_by_user_str(uint8_t *buf, size_t *len, const uint8_t *uname, const uint8_t *realm,
|
||||
const uint8_t *upwd, const uint8_t *nonce, SHATYPE shatype);
|
||||
bool stun_attr_add_integrity_by_user_short_term_str(uint8_t *buf, size_t *len, const uint8_t *uname, password_t pwd,
|
||||
SHATYPE shatype);
|
||||
size_t get_hmackey_size(SHATYPE shatype);
|
||||
|
||||
/*
|
||||
@ -208,33 +209,34 @@ size_t get_hmackey_size(SHATYPE shatype);
|
||||
|
||||
#define TURN_RANDOM_SIZE (sizeof(long))
|
||||
long turn_random(void);
|
||||
long turn_random_number(void);
|
||||
|
||||
int stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, hmackey_t key,
|
||||
SHATYPE shatype);
|
||||
int stun_calculate_hmac(const uint8_t *buf, size_t len, const uint8_t *key, size_t sz, uint8_t *hmac,
|
||||
unsigned int *hmac_len, SHATYPE shatype);
|
||||
bool stun_produce_integrity_key_str(const uint8_t *uname, const uint8_t *realm, const uint8_t *upwd, hmackey_t key,
|
||||
SHATYPE shatype);
|
||||
bool stun_calculate_hmac(const uint8_t *buf, size_t len, const uint8_t *key, size_t sz, uint8_t *hmac,
|
||||
unsigned int *hmac_len, SHATYPE shatype);
|
||||
|
||||
/* RFC 5780 */
|
||||
int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port);
|
||||
int stun_attr_add_change_request_str(uint8_t *buf, size_t *len, int change_ip, int change_port);
|
||||
bool stun_attr_get_change_request_str(stun_attr_ref attr, bool *change_ip, bool *change_port);
|
||||
bool stun_attr_add_change_request_str(uint8_t *buf, size_t *len, bool change_ip, bool change_port);
|
||||
int stun_attr_get_response_port_str(stun_attr_ref attr);
|
||||
int stun_attr_add_response_port_str(uint8_t *buf, size_t *len, uint16_t port);
|
||||
bool stun_attr_add_response_port_str(uint8_t *buf, size_t *len, uint16_t port);
|
||||
int stun_attr_get_padding_len_str(stun_attr_ref attr);
|
||||
int stun_attr_add_padding_str(uint8_t *buf, size_t *len, uint16_t padding_len);
|
||||
bool stun_attr_add_padding_str(uint8_t *buf, size_t *len, uint16_t padding_len);
|
||||
|
||||
/* HTTP */
|
||||
int is_http(const char *s, size_t blen);
|
||||
|
||||
/* OAUTH */
|
||||
int convert_oauth_key_data(const oauth_key_data *oakd, oauth_key *key, char *err_msg, size_t err_msg_size);
|
||||
int decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key,
|
||||
oauth_token *dtoken);
|
||||
int encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key,
|
||||
const oauth_token *dtoken, const uint8_t *nonce);
|
||||
bool convert_oauth_key_data(const oauth_key_data *oakd, oauth_key *key, char *err_msg, size_t err_msg_size);
|
||||
bool decode_oauth_token(const uint8_t *server_name, const encoded_oauth_token *etoken, const oauth_key *key,
|
||||
oauth_token *dtoken);
|
||||
bool encode_oauth_token(const uint8_t *server_name, encoded_oauth_token *etoken, const oauth_key *key,
|
||||
const oauth_token *dtoken, const uint8_t *nonce);
|
||||
|
||||
/* Encrypted password */
|
||||
void generate_new_enc_password(const char *pwd, char *result);
|
||||
int check_password(const char *pin, const char *pwd);
|
||||
bool check_password_equal(const char *pin, const char *pwd);
|
||||
|
||||
///////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@ -29,13 +29,17 @@
|
||||
*/
|
||||
|
||||
#include "ns_turn_msg_addr.h"
|
||||
#include "ns_turn_defs.h" // for nswap16, nswap32
|
||||
|
||||
#include <string.h> // for memcpy
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed, uint32_t mc, const uint8_t *tsx_id) {
|
||||
|
||||
if (!cfield || !clen || !ca || !tsx_id)
|
||||
if (!cfield || !clen || !ca || !tsx_id) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ca->ss.sa_family == AF_INET || ca->ss.sa_family == 0) {
|
||||
|
||||
@ -109,8 +113,9 @@ int stun_addr_encode(const ioa_addr *ca, uint8_t *cfield, int *clen, int xor_ed,
|
||||
|
||||
int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, uint32_t mc, const uint8_t *tsx_id) {
|
||||
|
||||
if (!cfield || !len || !ca || !tsx_id || (len < 8))
|
||||
if (!cfield || !len || !ca || !tsx_id || (len < 8)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (cfield[0] != 0) {
|
||||
return -1;
|
||||
@ -118,19 +123,21 @@ int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, u
|
||||
|
||||
int sa_family;
|
||||
|
||||
if (cfield[1] == 1)
|
||||
if (cfield[1] == 1) {
|
||||
sa_family = AF_INET;
|
||||
else if (cfield[1] == 2)
|
||||
} else if (cfield[1] == 2) {
|
||||
sa_family = AF_INET6;
|
||||
else
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
|
||||
ca->ss.sa_family = sa_family;
|
||||
|
||||
if (sa_family == AF_INET) {
|
||||
|
||||
if (len != 8)
|
||||
if (len != 8) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* IPv4 address */
|
||||
|
||||
@ -149,8 +156,9 @@ int stun_addr_decode(ioa_addr *ca, const uint8_t *cfield, int len, int xor_ed, u
|
||||
|
||||
/* IPv6 address */
|
||||
|
||||
if (len != 20)
|
||||
if (len != 20) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Port */
|
||||
ca->s6.sin6_port = ((const uint16_t *)cfield)[1];
|
||||
|
||||
@ -31,6 +31,7 @@
|
||||
#ifndef __LIB_TURN_MSG_ADDR__
|
||||
#define __LIB_TURN_MSG_ADDR__
|
||||
|
||||
#include "ns_turn_defs.h" // for ioa_addr, uint8_t, uint32_t
|
||||
#include "ns_turn_ioaddr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
@ -31,7 +31,9 @@
|
||||
#ifndef __LIB_TURN_MSG_DEFS__
|
||||
#define __LIB_TURN_MSG_DEFS__
|
||||
|
||||
#include "ns_turn_msg_defs_experimental.h"
|
||||
#include "ns_turn_defs.h" // for turn_time_t
|
||||
|
||||
#include "ns_turn_msg_defs_experimental.h" // IWYU pragma: export
|
||||
|
||||
///////////////////////////////////////////
|
||||
// http://www.iana.org/assignments/stun-parameters/stun-parameters.xhtml
|
||||
|
||||
@ -31,7 +31,7 @@
|
||||
#ifndef __IOADEFS__
|
||||
#define __IOADEFS__
|
||||
|
||||
#define TURN_SERVER_VERSION "4.6.2"
|
||||
#define TURN_SERVER_VERSION "4.6.3"
|
||||
#define TURN_SERVER_VERSION_NAME "Gorst"
|
||||
#ifndef TURN_SERVER_BUILD_INFO
|
||||
#define TURN_SERVER_BUILD_INFO ""
|
||||
@ -50,20 +50,21 @@
|
||||
#include <process.h>
|
||||
#include <ws2tcpip.h>
|
||||
#else
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h> // IWYU pragma: export
|
||||
#include <net/if.h> // IWYU pragma: export
|
||||
#include <netinet/in.h> // IWYU pragma: export
|
||||
#include <netinet/tcp.h> // IWYU pragma: export
|
||||
#include <strings.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h> // IWYU pragma: export
|
||||
#include <unistd.h> // IWYU pragma: export
|
||||
#endif
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdint.h>
|
||||
#include <stddef.h> // IWYU pragma: export
|
||||
#include <stdint.h> // IWYU pragma: export
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@ -184,6 +185,7 @@ typedef uint32_t turn_time_t;
|
||||
#error WRONG BYTE_ORDER SETTING
|
||||
#endif
|
||||
|
||||
// NOLINTBEGIN(clang-diagnostic-string-compare)
|
||||
#define STRCPY(dst, src) \
|
||||
do { \
|
||||
if ((const char *)(dst) != (const char *)(src)) { \
|
||||
@ -196,6 +198,7 @@ typedef uint32_t turn_time_t;
|
||||
} \
|
||||
} \
|
||||
} while (0)
|
||||
// NOLINTEND(clang-diagnostic-string-compare)
|
||||
|
||||
//////////////// Bufferevents /////////////////////
|
||||
|
||||
@ -219,7 +222,7 @@ typedef uint32_t turn_time_t;
|
||||
|
||||
////////////////////////////////////////////////////////
|
||||
|
||||
#if !defined(IPPROTO_SCTP)
|
||||
#if !defined(IPPROTO_SCTP) && !defined(TURN_NO_SCTP)
|
||||
#define TURN_NO_SCTP
|
||||
#endif
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user