diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 641e20b5f3..1ed5fb63b4 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -2,7 +2,7 @@ name: Bug report about: Create a report to help us improve title: "[BUG]" -labels: bug +labels: bug,needs-triage assignees: '' --- diff --git a/.github/ISSUE_TEMPLATE/questions-help.md b/.github/ISSUE_TEMPLATE/questions-help.md index 1cc48d57c9..83d1501847 100644 --- a/.github/ISSUE_TEMPLATE/questions-help.md +++ b/.github/ISSUE_TEMPLATE/questions-help.md @@ -2,7 +2,7 @@ name: Questions/Help about: Describe this issue template's purpose here. title: "[QUESTION]" -labels: question +labels: question,needs-triage assignees: '' --- diff --git a/.github/build_windows.bat b/.github/build_windows.bat index 17c70858c6..66fc5f2093 100644 --- a/.github/build_windows.bat +++ b/.github/build_windows.bat @@ -1,4 +1,4 @@ -call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat" +call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvars64.bat" amd64 mkdir build cd build cmd.exe /c cmake -G "NMake Makefiles" .. diff --git a/.github/github_deploy_key.enc b/.github/github_deploy_key.enc deleted file mode 100644 index 9be25b5032..0000000000 Binary files a/.github/github_deploy_key.enc and /dev/null differ diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 0000000000..9e77b11b21 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,380 @@ +name: WebRTC C SDK CI + +on: + push: + branches: + - develop + - master + pull_request: + branches: + - develop + - master +jobs: + clang-format-check: + runs-on: macos-latest + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install clang-format + run: | + brew install clang-format + clang-format --version + - name: Run clang format check + run: | + bash scripts/check-clang.sh + mac-os-build-clang: + runs-on: macos-latest + env: + CC: /usr/bin/clang + CXX: /usr/bin/clang++ + AWS_KVS_LOG_LEVEL: 2 + LDFLAGS: -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib + CPATH: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Build repository + run: | + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE + make + ./tst/webrtc_client_test + mac-os-build-gcc: + runs-on: macos-10.15 + env: + CC: gcc + CXX: g++ + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Build repository and run tests + run: | + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE + make + ./tst/webrtc_client_test + static-build-mac: + runs-on: macos-latest + env: + AWS_KVS_LOG_LEVEL: 2 + LDFLAGS: -L/Library/Developer/CommandLineTools/SDKs/MacOSX.sdk/usr/lib + CPATH: /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/ + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Build repository and run tests + run: | + mkdir build && cd build + cmake .. -DBUILD_STATIC_LIBS=TRUE -DBUILD_TEST=TRUE + make + ./tst/webrtc_client_test + linux-gcc-code-coverage: + runs-on: ubuntu-18.04 + env: + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Build repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DCODE_COVERAGE=TRUE -DBUILD_TEST=TRUE + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + - name: Code coverage + run: | + for test_file in $(find CMakeFiles/kvsWebrtcClient.dir CMakeFiles/kvsWebrtcSignalingClient.dir -name '*.gcno'); do gcov $test_file; done + bash <(curl -s https://codecov.io/bash) + address-sanitizer: + runs-on: ubuntu-18.04 + env: + ASAN_OPTIONS: detect_odr_violation=0:detect_leaks=1 + LSAN_OPTIONS: suppressions=../tst/suppressions/LSAN.supp + CC: clang-7 + CXX: clang++-7 + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get -y install clang-7 + - name: Build repository + run: | + # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DADDRESS_SANITIZER=TRUE + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + undefined-behavior-sanitizer: + runs-on: ubuntu-18.04 + env: + UBSAN_OPTIONS: halt_on_error=1 + CC: clang-7 + CXX: clang++-7 + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get -y install clang-7 + - name: Build repository + run: | + # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DUNDEFINED_BEHAVIOR_SANITIZER=TRUE + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + # memory-sanitizer: + # runs-on: ubuntu-18.04 + # env: + # CC: clang-7 + # CXX: clang++-7 + # AWS_KVS_LOG_LEVEL: 2 + # steps: + # - name: Clone repository + # uses: actions/checkout@v2 + # - name: Install dependencies + # run: | + # sudo apt-get update + # sudo apt-get -y install clang-7 + # - name: Build repository + # run: | + # sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + # mkdir build && cd build + # cmake .. -DMEMORY_SANITIZER=TRUE -DBUILD_TEST=TRUE + # make + # ulimit -c unlimited -S + # timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + thread-sanitizer: + runs-on: ubuntu-latest + env: + TSAN_OPTIONS: halt_on_error=1:suppressions=../tst/suppressions/TSAN.supp + CC: clang-7 + CXX: clang++-7 + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get -y install clang-7 + - name: Build repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DTHREAD_SANITIZER=TRUE + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + linux-gcc-4_4: + runs-on: ubuntu-18.04 + env: + AWS_KVS_LOG_LEVEL: 2 + CC: gcc-4.4 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install deps + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu/ trusty main' + sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu/ trusty universe' + sudo apt-get -q update + sudo apt-get -y install gcc-4.4 + sudo apt-get -y install gdb + - name: Build repository + run: | + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + static-build-linux: + runs-on: ubuntu-18.04 + container: + image: alpine:latest + env: + CC: gcc + CXX: g++ + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install dependencies + run: | + apk update + apk upgrade + apk add alpine-sdk cmake clang linux-headers perl bash openssl-dev + - name: Build Repository + run: | + mkdir build && cd build + cmake .. -DBUILD_STATIC_LIBS=TRUE -DBUILD_TEST=TRUE + make + mbedtls-ubuntu-gcc: + runs-on: ubuntu-latest + env: + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install deps + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test + sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu/ trusty main' + sudo add-apt-repository 'deb http://archive.ubuntu.com/ubuntu/ trusty universe' + sudo apt-get -q update + sudo apt-get -y install gcc-4.4 + sudo apt-get -y install gdb + - name: Build repository + run: | + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DUSE_OPENSSL=OFF -DUSE_MBEDTLS=ON + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + mbedtls-ubuntu-clang: + runs-on: ubuntu-18.04 + env: + CC: clang-7 + CXX: clang++-7 + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Install dependencies + run: | + sudo apt-get update + sudo apt-get -y install clang-7 + - name: Build repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE -DUSE_OPENSSL=OFF -DUSE_MBEDTLS=ON + make + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + sample-check: + if: github.repository == 'awslabs/amazon-kinesis-video-streams-webrtc-sdk-c' + runs-on: ubuntu-latest + env: + AWS_KVS_LOG_LEVEL: 2 + permissions: + id-token: write + contents: read + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Configure AWS Credentials + uses: aws-actions/configure-aws-credentials@v1 + with: + role-to-assume: ${{ secrets.AWS_ROLE_TO_ASSUME }} + role-session-name: ${{ secrets.AWS_ROLE_SESSION_NAME }} + aws-region: ${{ secrets.AWS_REGION }} + - name: Build repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. + make + cd .. + ./scripts/check-sample.sh + ubuntu-os-build: + runs-on: ubuntu-18.04 + env: + AWS_KVS_LOG_LEVEL: 2 + steps: + - name: Clone repository + uses: actions/checkout@v2 + - name: Build repository + run: | + # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_TEST=TRUE + make + ./tst/webrtc_client_test + # windows-msvc: + # runs-on: windows-2019 + # permissions: + # id-token: write + # contents: read + # steps: + # - name: Setup MSVC + # uses: ilammy/msvc-dev-cmd@v1 + # - name: Clone repository + # uses: actions/checkout@v2 + # - name: Build and run + # run: | + # choco install nasm strawberryperl + # $env:Path += ';C:\Strawberry\perl\site\bin;C:\Strawberry\perl\bin;C:\Strawberry\c\bin;C:\Program Files\NASM;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\lib;D:\a\amazon-kinesis-video-streams-producer-c\amazon-kinesis-video-streams-producer-c\open-source\bin' + # git config --system core.longpaths true + # .github/build_windows.bat + # cd tst && .\webrtc_client_test.exe --gtest_filter="-DataChannelFunctionalityTest.*:IceApiTest.*:IceFunctionalityTest.*:PeerConnectionFunctionalityTest.*:SignalingApiFunctionalityTest.*:TurnConnectionFunctionalityTest.*:RtpFunctionalityTest.marshallUnmarshallH264Data:RtpFunctionalityTest.packingUnpackingVerifySameH264Frame:RtcpFunctionalityTest.onRtcpPacketCompound:RtcpFunctionalityTest.twcc3" + arm64-cross-compilation: + runs-on: ubuntu-latest + env: + CC: aarch64-linux-gnu-gcc + CXX: aarch64-linux-gnu-g++ + steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu + - name: Clone repository + uses: actions/checkout@v2 + - name: Build Repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_OPENSSL=TRUE -DBUILD_OPENSSL_PLATFORM=linux-generic64 -DBUILD_LIBSRTP_HOST_PLATFORM=x86_64-unknown-linux-gnu -DBUILD_LIBSRTP_DESTINATION_PLATFORM=arm-unknown-linux-uclibcgnueabi + make + linux-aarch64-cross-compilation: + runs-on: ubuntu-latest + env: + CC: aarch64-linux-gnu-gcc + CXX: aarch64-linux-gnu-g++ + steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt-get -y install gcc-aarch64-linux-gnu g++-aarch64-linux-gnu binutils-aarch64-linux-gnu + - name: Clone repository + uses: actions/checkout@v2 + - name: Build Repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_OPENSSL=TRUE -DBUILD_OPENSSL_PLATFORM=linux-aarch64 -DBUILD_LIBSRTP_HOST_PLATFORM=x86_64-unknown-linux-gnu -DBUILD_LIBSRTP_DESTINATION_PLATFORM=arm-unknown-linux-uclibcgnueabi + make + arm32-cross-compilation: + runs-on: ubuntu-latest + env: + CC: arm-linux-gnueabi-gcc + CXX: arm-linux-gnueabi-g++ + steps: + - name: Install dependencies + run: | + sudo apt update + sudo apt-get -y install gcc-arm-linux-gnueabi g++-arm-linux-gnueabi binutils-arm-linux-gnueabi + - name: Clone repository + uses: actions/checkout@v2 + - name: Build Repository + run: | + sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' + mkdir build && cd build + cmake .. -DBUILD_OPENSSL=TRUE -DBUILD_OPENSSL_PLATFORM=linux-generic32 -DBUILD_LIBSRTP_HOST_PLATFORM=x86_64-unknown-linux-gnu -DBUILD_LIBSRTP_DESTINATION_PLATFORM=arm-unknown-linux-uclibcgnueabi + make diff --git a/.github/workflows/close-stale-issues.yml b/.github/workflows/close-stale-issues.yml index a1745b1b92..4f721c936b 100644 --- a/.github/workflows/close-stale-issues.yml +++ b/.github/workflows/close-stale-issues.yml @@ -10,18 +10,22 @@ jobs: runs-on: ubuntu-latest name: Close stale issues steps: - - uses: actions/stale@v4.0.0 + - uses: aws-actions/stale-issue-cleanup@v3 with: - stale-issue-message: It looks like this issue has not been active for a long time. If the issue is not resolved, please add an update to the ticket, else it will be automatically resolved in a few days. - close-issue-message: The issue has been stale for a while and hence it has been auto-closed. If the issue persists, feel free to open a new issue with details. + ancient-issue-message: This is a very old issue. We encourage you to check if this is still an issue in the latest release and if you find that this is still a problem, please feel free to open a new one. + stale-issue-message: It looks like this issue has not been active for 10 days. If the issue is not resolved, please add an update to the ticket, else it will be automatically resolved in a few days. # labels to be added stale-issue-label: closing-soon - any-of-labels: question,bug + exempt-issue-labels: enhancement,pending-research,pending-action,needs-triage + response-requested-label: pending-response + + closed-for-staleness-label: closed-for-staleness # SLAs - days-before-issue-stale: 7 - days-before-issue-close: 3 + days-before-stale: 7 + days-before-close: 3 + days-before-ancient: 180 repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml new file mode 100644 index 0000000000..dd7093eacb --- /dev/null +++ b/.github/workflows/codecov.yml @@ -0,0 +1,29 @@ +name: Codecov for WebRTC C SDK +on: + push: + branches: + - develop + - master + pull_request: + branches: + - develop + - master +jobs: + linux-gcc-codecov: + runs-on: ubuntu-latest + steps: + - name: Fetch + uses: actions/checkout@v2 + with: + fetch-depth: 2 + - name: Run code coverage + run: | + mkdir build + cd build + cmake .. -DCODE_COVERAGE=TRUE -DBUILD_TEST=TRUE + make + export AWS_KVS_LOG_LEVEL=3 + ulimit -c unlimited -S + timeout --signal=SIGABRT 60m ./tst/webrtc_client_test + for test_file in $(find CMakeFiles/kvsWebrtcClient.dir CMakeFiles/kvsWebrtcSignalingClient.dir -name '*.gcno'); do gcov $test_file; done + bash <(curl -s https://codecov.io/bash) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 48df0f11f6..ec9d11cfb0 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -2,10 +2,10 @@ name: "CodeQL" on: push: - branches: [ master ] + branches: [ develop, master ] pull_request: # The branches below must be a subset of the branches above - branches: [ master ] + branches: [ develop, master ] jobs: analyze: diff --git a/.github/workflows/doxygen-gh-pages.yml b/.github/workflows/doxygen-gh-pages.yml new file mode 100644 index 0000000000..488b4fb1fd --- /dev/null +++ b/.github/workflows/doxygen-gh-pages.yml @@ -0,0 +1,29 @@ +name: Doxygen GitHub Pages Deploy Action WebRTC C SDK + +on: + push: + branches: + - master + - develop + +jobs: + generate-and-deploy-doxygen: + runs-on: ubuntu-latest + steps: + - name: Checkout repository + uses: actions/checkout@v2 + + - name: Install requirements + run: sudo apt-get install doxygen graphviz -y + shell: bash + + - name: Generate Doxygen Documentation + run: doxygen Doxyfile + shell: bash + + - name: Deploy + uses: JamesIves/github-pages-deploy-action@v4.2.5 + with: + folder: doc/html + branch: gh-pages + \ No newline at end of file diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index 95d952919d..0000000000 --- a/.travis.yml +++ /dev/null @@ -1,270 +0,0 @@ -language: cpp -sudo: true - -branches: - only: - - master - - develop - -cache: -- directories: - - $HOME/.cache - - -services: - - docker - -addons: - apt: - packages: - - gdb - - docker-ce - -script: - - export AWS_KVS_LOG_LEVEL=3 - - make - - ulimit -c unlimited -S - - timeout --signal=SIGABRT 60m ./tst/webrtc_client_test - -after_failure: - - for i in $(find ./ -maxdepth 1 -name 'core*' -print); do gdb $(pwd)/tst/webrtc_client_test core* -ex "thread apply all bt" -ex "set pagination 0" -batch; done; - -matrix: - # MemorySanitizer and UndefinedBehaviorSanitizer are still WIP - allow_failures: - - env: allowTestFail=true - - include: - #clang check - - name: "clang-format Check" - os: linux - compiler: clang - before_script: - - sudo apt-get -q update - - sudo apt-get -y install clang-format - - mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST=TRUE - script: - - cd .. - - bash scripts/check-clang.sh - - # MacOS Builds - - name: "OSX GCC" - os: osx - compiler: gcc - before_script: - - mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE - script: - - make - - export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:`pwd`/../open-source/lib" - - ./tst/webrtc_client_test - after_failure: skip # timeout not available on MacOS - - - name: "OSX Clang" - os: osx - compiler: clang - before_script: - - mkdir build && cd build && cmake .. -DBUILD_TEST=TRUE -DCOMPILER_WARNINGS=TRUE - script: - - make - - export DYLD_LIBRARY_PATH="$DYLD_LIBRARY_PATH:`pwd`/../open-source/lib" - - ./tst/webrtc_client_test || travis_terminate 1; - # Execute selected tests without auth integration - - unset AWS_ACCESS_KEY_ID - - unset AWS_SECRET_ACCESS_KEY - - ./tst/webrtc_client_test --gtest_break_on_failure --gtest_filter="SignalingApiFunctionalityTest.*:SignalingApiTest.*:TurnConnectionFunctionalityTest.*" - after_failure: skip # timeout not available on MacOS - - # Code Coverage - - name: "Linux GCC Code Coverage" - os: linux - compiler: gcc - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: - - mkdir build && cd build && cmake .. -DCODE_COVERAGE=TRUE -DBUILD_TEST=TRUE - after_success: - - for test_file in $(find CMakeFiles/kvsWebrtcClient.dir CMakeFiles/kvsWebrtcSignalingClient.dir -name '*.gcno'); do gcov $test_file; done - - bash <(curl -s https://codecov.io/bash) - - # AddressSanitizer - - name: "Linux Clang AddressSanitizer" - os: linux - compiler: clang - env: - - ASAN_OPTIONS=detect_odr_violation=0:detect_leaks=1 - - LSAN_OPTIONS=suppressions=../tst/suppressions/LSAN.supp - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST=TRUE -DADDRESS_SANITIZER=TRUE - - # UndefinedBehaviorSanitizer - - name: "Linux Clang UndefinedBehaviorSanitizer" - os: linux - compiler: clang - env: UBSAN_OPTIONS=halt_on_error=1 - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST=TRUE -DUNDEFINED_BEHAVIOR_SANITIZER=TRUE - - # MemorySanitizer - - name: "Linux Clang MemorySanitizer" - env: allowTestFail=true - before_install: - # TODO: Remove the following 2 lines. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - echo '{"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' | sudo tee /etc/docker/daemon.json - - sudo service docker restart - - mkdir build - - docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -w /src/build -dit --name msan-tester -v $(pwd):/src seaduboi/kvs-msan-tester - - msan-tester() { docker exec -it msan-tester "$@"; } - script: - - msan-tester cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_DEPENDENCIES=FALSE -DBUILD_TEST=TRUE -DMEMORY_SANITIZER=TRUE -DCMAKE_CXX_FLAGS="-stdlib=libc++ -L/usr/src/libcxx_msan/lib -lc++abi -I/usr/src/libcxx_msan/include -I/usr/src/libcxx_msan/include/c++/v1 -fsanitize=memory -fno-omit-frame-pointer -fno-optimize-sibling-calls -fsanitize-memory-track-origins" - - msan-tester make - - msan-tester ./tst/webrtc_client_test - after_failure: skip # no coredumps in container - - # ThreadSanitizer - - name: "Linux Clang ThreadSanitizer" - os: linux - compiler: clang - env: TSAN_OPTIONS=halt_on_error=1:suppressions=../tst/suppressions/TSAN.supp - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: mkdir build && cd build && cmake .. -DCMAKE_BUILD_TYPE=Debug -DBUILD_TEST=TRUE -DTHREAD_SANITIZER=TRUE - - # Old Version GCC 4.4 - - name: "Linux GCC 4.4 Build" - os: linux - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get -q update - - sudo apt-get -y install gcc-4.4 - - sudo apt-get -y install gdb - compiler: gcc - before_script: export CC=gcc-4.4 && mkdir build && cd build && cmake .. -DBUILD_TEST=TRUE - - # Static Build - - name: "Static Build" - before_install: - # TODO: Remove the following 2 lines. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - echo '{"ipv6":true,"fixed-cidr-v6":"2001:db8:1::/64"}' | sudo tee /etc/docker/daemon.json - - sudo service docker restart - - mkdir build - - docker run -e AWS_ACCESS_KEY_ID -e AWS_SECRET_ACCESS_KEY -w /src/build -dit --security-opt=seccomp=.github/default.json --name alpine -v $(pwd):/src alpine:latest - - alpine() { docker exec -it alpine "$@"; } - install: - - alpine apk update - - alpine apk upgrade - - alpine apk add alpine-sdk cmake clang linux-headers perl bash openssl-dev - script: - - alpine cmake .. -DBUILD_STATIC_LIBS=TRUE -DBUILD_TEST=TRUE - - alpine make - # ldd will return non-zero when there's no dynamic link. So, the positive value for static builds is non-zero - - alpine ../scripts/check-static-build.sh || travis_terminate 1 - - alpine ./tst/webrtc_client_test - after_failure: skip # no coredumps in container - - # Cross-compilation to ARM, no tests are run - - name: "ARM Cross-compilation" - os: linux - addons: - apt: - packages: - - gcc-arm-linux-gnueabi - - g++-arm-linux-gnueabi - - binutils-arm-linux-gnueabi - compiler: gcc - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: - - export CC=arm-linux-gnueabi-gcc CXX=arm-linux-gnueabi-g++ - - mkdir build && cd build - - cmake .. -DBUILD_OPENSSL=TRUE -DBUILD_OPENSSL_PLATFORM=linux-generic32 -DBUILD_LIBSRTP_HOST_PLATFORM=x86_64-unknown-linux-gnu -DBUILD_LIBSRTP_DESTINATION_PLATFORM=arm-unknown-linux-uclibcgnueabi - script: make - - - name: "mbedTLS - Linux GCC 4.4 Build" - os: linux - compiler: gcc - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get -q update - - sudo apt-get -y install gcc-4.4 - - sudo apt-get -y install gdb - before_script: mkdir build && cd build && cmake .. -DBUILD_TEST=TRUE -DUSE_OPENSSL=OFF -DUSE_MBEDTLS=ON - - - name: "mbedTLS - Linux Clang" - os: linux - compiler: clang - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - before_script: mkdir build && cd build && cmake .. -DBUILD_TEST=TRUE -DUSE_OPENSSL=OFF -DUSE_MBEDTLS=ON - - - name: "Windows MSVC" - env: allowTestFail=true - os: windows - script: - - choco install nasm strawberryperl - - unset CC CC_FOR_BUILD CXX CXX_FOR_BUILD # We want to use MSVC - - export "PATH=/c/Strawberry/perl/site/bin:/c/Strawberry/perl/bin:/c/Strawberry/c/bin:/c/Program Files/NASM:`pwd`/open-source/lib:`pwd`/open-source/bin:$PATH" - - .github/build_windows.bat - - cd build/tst && ./webrtc_client_test.exe --gtest_filter="-DataChannelFunctionalityTest.*:IceApiTest.*:IceFunctionalityTest.*:PeerConnectionFunctionalityTest.*:SignalingApiFunctionalityTest.*:TurnConnectionFunctionalityTest.*:RtpFunctionalityTest.marshallUnmarshallH264Data:RtpFunctionalityTest.packingUnpackingVerifySameH264Frame:RtcpFunctionalityTest.onRtcpPacketCompound:RtcpFunctionalityTest.twcc3" - - - name: "Sample check" - os: linux - compiler: gcc - before_install: - # TODO: Remove the following line. This is only a workaround for enabling IPv6, https://github.com/travis-ci/travis-ci/issues/8891. - - sudo sh -c 'echo 0 > /proc/sys/net/ipv6/conf/all/disable_ipv6' - - sudo add-apt-repository -y ppa:ubuntu-toolchain-r/test - - sudo apt-get -q update - - sudo apt-get -y install gcc-4.4 - before_script: mkdir build && cd build && cmake .. - script: - - make - - cd .. - - ./scripts/check-sample.sh - - # Generate Doxygen - - name: "Generate Doxygen" - if: type = push - before_install: - - docker run -w /src/.github -dit --name alpine -v $(pwd):/src alpine - - alpine() { docker exec -it alpine "$@"; } - - alpine apk update - - alpine apk add doxygen graphviz - - alpine apk add --no-cache ttf-freefont - script: - # Add SSH key to agent - - | - eval "$(ssh-agent -s)" - openssl aes-256-cbc -K $encrypted_d627db542948_key -iv $encrypted_d627db542948_iv -in .github/github_deploy_key.enc -out .github/github_deploy_key -d - chmod 600 .github/github_deploy_key - ssh-add .github/github_deploy_key - rm .github/github_deploy_key - # Generate doxygen in container, need latest version - - alpine doxygen Doxyfile - - alpine chmod -R 777 doc - - mv .github/doc/html /tmp - # Unshallow repo - - | - git remote rm origin - git remote add origin git@github.com:awslabs/amazon-kinesis-video-streams-webrtc-sdk-c.git - git fetch - # Move to gh-pages and create new commit - - | - git checkout gh-pages - rm -rf * .github - mv /tmp/html/* . - # Commit and push - - | - git add . - git commit -m "Auto-generated from travis" - git push diff --git a/.github/Doxyfile b/Doxyfile similarity index 100% rename from .github/Doxyfile rename to Doxyfile diff --git a/.github/DoxygenLayout.xml b/DoxygenLayout.xml similarity index 100% rename from .github/DoxygenLayout.xml rename to DoxygenLayout.xml diff --git a/.github/Introduction.md b/Introduction.md similarity index 100% rename from .github/Introduction.md rename to Introduction.md diff --git a/README.md b/README.md index 8dc9449b83..a824f36eb3 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@

Pure C WebRTC Client for Amazon Kinesis Video Streams

- Build Status Coverage Status

@@ -73,7 +72,7 @@ If you do wish to link to existing libraries you can use the following flags to #### Cross-Compilation -If you wish to cross-compile `CC` and `CXX` are respected when building the library and all its dependencies. You will also need to set `BUILD_OPENSSL_PLATFORM`, `BUILD_LIBSRTP_HOST_PLATFORM` and `BUILD_LIBSRTP_DESTINATION_PLATFORM`. See our [.travis.yml](.travis.yml) for an example of this. Every commit is cross compiled to ensure that it continues to work. +If you wish to cross-compile `CC` and `CXX` are respected when building the library and all its dependencies. You will also need to set `BUILD_OPENSSL_PLATFORM`, `BUILD_LIBSRTP_HOST_PLATFORM` and `BUILD_LIBSRTP_DESTINATION_PLATFORM`. See our codecov.io for an example of this. Every commit is cross compiled to ensure that it continues to work. #### Static Builds diff --git a/samples/Common.c b/samples/Common.c index 8270e2cb09..d03f5c64b0 100644 --- a/samples/Common.c +++ b/samples/Common.c @@ -12,6 +12,13 @@ VOID sigintHandler(INT32 sigNum) } } +STATUS signalingCallFailed(STATUS status) +{ + return (STATUS_SIGNALING_GET_TOKEN_CALL_FAILED == status || STATUS_SIGNALING_DESCRIBE_CALL_FAILED == status || + STATUS_SIGNALING_CREATE_CALL_FAILED == status || STATUS_SIGNALING_GET_ENDPOINT_CALL_FAILED == status || + STATUS_SIGNALING_GET_ICE_CONFIG_CALL_FAILED == status || STATUS_SIGNALING_CONNECT_CALL_FAILED == status); +} + VOID onDataChannelMessage(UINT64 customData, PRtcDataChannel pDataChannel, BOOL isBinary, PBYTE pMessage, UINT32 pMessageLen) { UNUSED_PARAM(customData); @@ -886,32 +893,32 @@ STATUS getIceCandidatePairStatsCallback(UINT32 timerId, UINT64 currentTime, UINT pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.nominated ? "nominated" : "not nominated"); averageNumberOfPacketsSentPerSecond = - (DOUBLE)(pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsSent - - pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfPacketsSent) / + (DOUBLE) (pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsSent - + pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfPacketsSent) / (DOUBLE) currentMeasureDuration; DLOGD("Packet send rate: %lf pkts/sec", averageNumberOfPacketsSentPerSecond); averageNumberOfPacketsReceivedPerSecond = - (DOUBLE)(pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsReceived - - pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfPacketsReceived) / + (DOUBLE) (pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsReceived - + pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfPacketsReceived) / (DOUBLE) currentMeasureDuration; DLOGD("Packet receive rate: %lf pkts/sec", averageNumberOfPacketsReceivedPerSecond); - outgoingBitrate = (DOUBLE)((pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.bytesSent - - pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfBytesSent) * - 8.0) / + outgoingBitrate = (DOUBLE) ((pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.bytesSent - + pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfBytesSent) * + 8.0) / currentMeasureDuration; DLOGD("Outgoing bit rate: %lf bps", outgoingBitrate); - incomingBitrate = (DOUBLE)((pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.bytesReceived - - pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfBytesReceived) * - 8.0) / + incomingBitrate = (DOUBLE) ((pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.bytesReceived - + pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevNumberOfBytesReceived) * + 8.0) / currentMeasureDuration; DLOGD("Incoming bit rate: %lf bps", incomingBitrate); averagePacketsDiscardedOnSend = - (DOUBLE)(pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsDiscardedOnSend - - pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevPacketsDiscardedOnSend) / + (DOUBLE) (pSampleConfiguration->rtcIceCandidatePairMetrics.rtcStatsObject.iceCandidatePairStats.packetsDiscardedOnSend - + pSampleConfiguration->sampleStreamingSessionList[i]->rtcMetricsHistory.prevPacketsDiscardedOnSend) / (DOUBLE) currentMeasureDuration; DLOGD("Packet discard rate: %lf pkts/sec", averagePacketsDiscardedOnSend); @@ -1156,10 +1163,18 @@ STATUS sessionCleanupWait(PSampleConfiguration pSampleConfiguration) } // Check if we need to re-create the signaling client on-the-fly - if (ATOMIC_LOAD_BOOL(&pSampleConfiguration->recreateSignalingClient) && - STATUS_SUCCEEDED(signalingClientFetchSync(pSampleConfiguration->signalingClientHandle))) { - // Re-set the variable again - ATOMIC_STORE_BOOL(&pSampleConfiguration->recreateSignalingClient, FALSE); + if (ATOMIC_LOAD_BOOL(&pSampleConfiguration->recreateSignalingClient)) { + retStatus = signalingClientFetchSync(pSampleConfiguration->signalingClientHandle); + if (STATUS_SUCCEEDED(retStatus)) { + // Re-set the variable again + ATOMIC_STORE_BOOL(&pSampleConfiguration->recreateSignalingClient, FALSE); + } else if (signalingCallFailed(retStatus)) { + printf("[KVS Common] recreating Signaling Client\n"); + freeSignalingClient(&pSampleConfiguration->signalingClientHandle); + createSignalingClientSync(&pSampleConfiguration->clientInfo, &pSampleConfiguration->channelInfo, + &pSampleConfiguration->signalingClientCallbacks, pSampleConfiguration->pCredentialProvider, + &pSampleConfiguration->signalingClientHandle); + } } // Check the signaling client state and connect if needed diff --git a/samples/kvsWebRTCClientMaster.c b/samples/kvsWebRTCClientMaster.c index d7e29e1506..a8a4348ec2 100644 --- a/samples/kvsWebRTCClientMaster.c +++ b/samples/kvsWebRTCClientMaster.c @@ -292,7 +292,7 @@ PVOID sendVideoPackets(PVOID args) CHK_LOG_ERR(retStatus); - return (PVOID)(ULONG_PTR) retStatus; + return (PVOID) (ULONG_PTR) retStatus; } PVOID sendAudioPackets(PVOID args) @@ -360,7 +360,7 @@ PVOID sendAudioPackets(PVOID args) CleanUp: - return (PVOID)(ULONG_PTR) retStatus; + return (PVOID) (ULONG_PTR) retStatus; } PVOID sampleReceiveVideoFrame(PVOID args) @@ -380,5 +380,5 @@ PVOID sampleReceiveVideoFrame(PVOID args) CleanUp: - return (PVOID)(ULONG_PTR) retStatus; + return (PVOID) (ULONG_PTR) retStatus; } diff --git a/samples/kvsWebRTCClientViewer.c b/samples/kvsWebRTCClientViewer.c index 189a8706db..218f920426 100644 --- a/samples/kvsWebRTCClientViewer.c +++ b/samples/kvsWebRTCClientViewer.c @@ -17,14 +17,15 @@ VOID dataChannelOnMessageCallback(UINT64 customData, PRtcDataChannel pDataChanne } // onOpen callback for the onOpen event of a viewer created data channel -VOID dataChannelOnOpenCallback(UINT64 customData, PRtcDataChannel pDataChannel) { +VOID dataChannelOnOpenCallback(UINT64 customData, PRtcDataChannel pDataChannel) +{ STATUS retStatus = STATUS_SUCCESS; DLOGI("New DataChannel has been opened %s \n", pDataChannel->name); dataChannelOnMessage(pDataChannel, customData, dataChannelOnMessageCallback); ATOMIC_INCREMENT((PSIZE_T) customData); // Sending first message to the master over the data channel retStatus = dataChannelSend(pDataChannel, FALSE, (PBYTE) VIEWER_DATA_CHANNEL_MESSAGE, STRLEN(VIEWER_DATA_CHANNEL_MESSAGE)); - if(retStatus != STATUS_SUCCESS){ + if (retStatus != STATUS_SUCCESS) { DLOGI("[KVS Viewer] dataChannelSend(): operation returned status code: 0x%08x \n", retStatus); } } @@ -204,7 +205,7 @@ INT32 main(INT32 argc, CHAR* argv[]) // Creating a new datachannel on the peer connection of the existing sample streaming session retStatus = createDataChannel(pPeerConnection, pChannelName, NULL, &pDataChannel); - if(retStatus != STATUS_SUCCESS) { + if (retStatus != STATUS_SUCCESS) { printf("[KVS Viewer] createDataChannel(): operation returned status code: 0x%08x \n", retStatus); goto CleanUp; } @@ -212,7 +213,7 @@ INT32 main(INT32 argc, CHAR* argv[]) // Setting a callback for when the data channel is open retStatus = dataChannelOnOpen(pDataChannel, (UINT64) &datachannelLocalOpenCount, dataChannelOnOpenCallback); - if(retStatus != STATUS_SUCCESS) { + if (retStatus != STATUS_SUCCESS) { printf("[KVS Viewer] dataChannelOnOpen(): operation returned status code: 0x%08x \n", retStatus); goto CleanUp; } diff --git a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h index 55adc47393..bf91f41c48 100644 --- a/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h +++ b/src/include/com/amazonaws/kinesis/video/webrtcclient/Include.h @@ -301,7 +301,6 @@ extern "C" { #define STATUS_SIGNALING_INVALID_CLIENT_INFO_CACHE_FILE_PATH_LEN STATUS_SIGNALING_BASE + 0x00000033 #define STATUS_SIGNALING_LWS_CALL_FAILED STATUS_SIGNALING_BASE + 0x00000034 - /*!@} */ ///////////////////////////////////////////////////// @@ -1182,19 +1181,20 @@ typedef struct { * @brief Populate Signaling client with client ID and application log level */ typedef struct { - UINT32 version; //!< Version of the structure - CHAR clientId[MAX_SIGNALING_CLIENT_ID_LEN + 1]; //!< Client id to use. Defines if the client is a producer/consumer - UINT32 loggingLevel; //!< Verbosity level for the logging. One of LOG_LEVEL_XXX - //!< values or the default verbosity will be assumed. Currently, - //!< default value is LOG_LEVEL_WARNING - PCHAR cacheFilePath; //!< File cache path override. The default - //!< path is "./.SignalingCache_vN" which might not work for - //!< devices which have read only partition where the code is - //!< located. For default value or when file caching is not - //!< being used this value can be NULL or point to an EMPTY_STRING. - KvsRetryStrategyCallbacks signalingRetryStrategyCallbacks; //!< Retry strategy callbacks used while creating signaling client - INT32 signalingClientCreationMaxRetryAttempts; //!< Max attempts to create signaling client before returning error to the caller - UINT32 stateMachineRetryCountReadOnly; //!< Retry count of state machine. Note that this **MUST NOT** be modified by the user. It is a read only field + UINT32 version; //!< Version of the structure + CHAR clientId[MAX_SIGNALING_CLIENT_ID_LEN + 1]; //!< Client id to use. Defines if the client is a producer/consumer + UINT32 loggingLevel; //!< Verbosity level for the logging. One of LOG_LEVEL_XXX + //!< values or the default verbosity will be assumed. Currently, + //!< default value is LOG_LEVEL_WARNING + PCHAR cacheFilePath; //!< File cache path override. The default + //!< path is "./.SignalingCache_vN" which might not work for + //!< devices which have read only partition where the code is + //!< located. For default value or when file caching is not + //!< being used this value can be NULL or point to an EMPTY_STRING. + KvsRetryStrategyCallbacks signalingRetryStrategyCallbacks; //!< Retry strategy callbacks used while creating signaling client + INT32 signalingClientCreationMaxRetryAttempts; //!< Max attempts to create signaling client before returning error to the caller + UINT32 stateMachineRetryCountReadOnly; //!< Retry count of state machine. Note that this **MUST NOT** be modified by the user. It is a read only + //!< field } SignalingClientInfo, *PSignalingClientInfo; /** diff --git a/src/source/Ice/IceAgent.c b/src/source/Ice/IceAgent.c index 18f0a1a80c..3747b956cc 100644 --- a/src/source/Ice/IceAgent.c +++ b/src/source/Ice/IceAgent.c @@ -1233,6 +1233,15 @@ STATUS iceCandidatePairCheckConnection(PStunPacket pStunBindingRequest, PIceAgen CHK(pStunAttributePriority != NULL, STATUS_INVALID_ARG); + if (pIceCandidatePair->local->ipAddress.family == KVS_IP_FAMILY_TYPE_IPV4) { + DLOGD("remote ip:%u.%u.%u.%u, port:%u, local ip:%u.%u.%u.%u, port:%u", pIceCandidatePair->remote->ipAddress.address[0], + pIceCandidatePair->remote->ipAddress.address[1], pIceCandidatePair->remote->ipAddress.address[2], + pIceCandidatePair->remote->ipAddress.address[3], pIceCandidatePair->remote->ipAddress.address[0], + pIceCandidatePair->remote->ipAddress.port, pIceCandidatePair->local->ipAddress.address[1], + pIceCandidatePair->local->ipAddress.address[2], pIceCandidatePair->local->ipAddress.address[3], + pIceCandidatePair->local->ipAddress.address[0], pIceCandidatePair->local->ipAddress.port); + } + // update priority and transaction id pStunAttributePriority->priority = pIceCandidatePair->local->priority; CHK_STATUS(iceUtilsGenerateTransactionId(pStunBindingRequest->header.transactionId, ARRAY_SIZE(pStunBindingRequest->header.transactionId))); @@ -2247,11 +2256,12 @@ STATUS incomingRelayedDataHandler(UINT64 customData, PSocketConnection pSocketCo STATUS retStatus = STATUS_SUCCESS; PIceCandidate pRelayedCandidate = (PIceCandidate) customData; // this should be more than enough. Usually the number of channel data in each tcp message is around 4 - TurnChannelData turnChannelData[DEFAULT_TURN_CHANNEL_DATA_BUFFER_SIZE]; + TurnChannelData turnChannelData[DEFAULT_TURN_CHANNEL_DATA_BUFFER_SIZE] = {0}; UINT32 turnChannelDataCount = ARRAY_SIZE(turnChannelData), i = 0; CHK(pRelayedCandidate != NULL && pSocketConnection != NULL, STATUS_NULL_ARG); + DLOGV("Candidate id: %s", pRelayedCandidate->id); CHK_STATUS(turnConnectionIncomingDataHandler(pRelayedCandidate->pTurnConnection, pBuffer, bufferLen, pSrc, pDest, turnChannelData, &turnChannelDataCount)); for (i = 0; i < turnChannelDataCount; ++i) { @@ -2282,6 +2292,7 @@ STATUS incomingDataHandler(UINT64 customData, PSocketConnection pSocketConnectio // for stun packets, first 8 bytes are 4 byte type and length, then 4 byte magic byte if ((bufferLen < 8 || !IS_STUN_PACKET(pBuffer)) && pIceAgent->iceAgentCallbacks.inboundPacketFn != NULL) { // release lock early + MUTEX_UNLOCK(pIceAgent->lock); locked = FALSE; pIceAgent->iceAgentCallbacks.inboundPacketFn(pIceAgent->iceAgentCallbacks.customData, pBuffer, bufferLen); @@ -2441,7 +2452,9 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalResponsesReceived++; retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); if (retStatus != STATUS_SUCCESS) { - DLOGW("Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x)", retStatus); + DLOGW("Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x), " + "stunBindingRequest", + retStatus); } else { pIceAgent->rtcIceServerDiagnostics[pIceCandidate->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); @@ -2469,6 +2482,7 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS "Cannot find candidate pair with local candidate %s and remote candidate %s. Dropping STUN binding success response", ipAddrStr2, ipAddrStr); } + DLOGV("Pair binding response! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); retStatus = hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime); if (retStatus != STATUS_SUCCESS) { DLOGW("Unable to fetch request Timestamp from the hash table. No update to RTT for the pair (error code: 0x%08x)", retStatus); @@ -2485,7 +2499,8 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalResponsesReceived++; retStatus = hashTableGet(pIceAgent->requestTimestampDiagnostics, checkSum, &requestSentTime); if (retStatus != STATUS_SUCCESS) { - DLOGW("Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x)", retStatus); + DLOGW("Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x), typeRelayed", + retStatus); } else { pIceAgent->rtcIceServerDiagnostics[pIceCandidatePair->local->iceServerIndex].totalRoundTripTime += GETTIME() - requestSentTime; CHK_STATUS(hashTableRemove(pIceAgent->requestTimestampDiagnostics, checkSum)); @@ -2513,10 +2528,13 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS } if (pIceCandidatePair->state != ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { + DLOGV("Pair succeeded! %s %s", pIceCandidatePair->local->id, pIceCandidatePair->remote->id); pIceCandidatePair->state = ICE_CANDIDATE_PAIR_STATE_SUCCEEDED; retStatus = hashTableGet(pIceCandidatePair->requestSentTime, checkSum, &requestSentTime); if (retStatus != STATUS_SUCCESS) { - DLOGW("Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x)", retStatus); + DLOGW( + "Unable to fetch request Timestamp from the hash table. No update to totalRoundTripTime (error code: 0x%08x), stateSucceeded", + retStatus); } else { pIceCandidatePair->roundTripTime = GETTIME() - requestSentTime; DLOGD("Ice candidate pair %s_%s is connected. Round trip time: %" PRIu64 "ms", pIceCandidatePair->local->id, @@ -2537,12 +2555,21 @@ STATUS handleStunPacket(PIceAgent pIceAgent, PBYTE pBuffer, UINT32 bufferLen, PS break; default: - CHK_STATUS(hexEncode(pBuffer, bufferLen, NULL, &hexStrLen)); - hexStr = MEMCALLOC(1, hexStrLen * SIZEOF(CHAR)); - CHK(hexStr != NULL, STATUS_NOT_ENOUGH_MEMORY); - CHK_STATUS(hexEncode(pBuffer, bufferLen, hexStr, &hexStrLen)); - DLOGW("Dropping unrecognized STUN packet. Packet type: 0x%02x. Packet content: \n\t%s", stunPacketType, hexStr); - SAFE_MEMFREE(hexStr); + if (!IS_STUN_PACKET(pBuffer)) { + CHK_STATUS(hexEncode(pBuffer, bufferLen, NULL, &hexStrLen)); + hexStr = MEMCALLOC(1, hexStrLen * SIZEOF(CHAR)); + CHK(hexStr != NULL, STATUS_NOT_ENOUGH_MEMORY); + CHK_STATUS(hexEncode(pBuffer, bufferLen, hexStr, &hexStrLen)); + DLOGW("Dropping unrecognized STUN packet. Packet type: 0x%02x. Packet content: \n\t%s", stunPacketType, hexStr); + SAFE_MEMFREE(hexStr); + } else if (STUN_PACKET_IS_TYPE_ERROR(pBuffer)) { + CHK_STATUS(hexEncode(pBuffer, bufferLen, NULL, &hexStrLen)); + hexStr = MEMCALLOC(1, hexStrLen * SIZEOF(CHAR)); + CHK(hexStr != NULL, STATUS_NOT_ENOUGH_MEMORY); + CHK_STATUS(hexEncode(pBuffer, bufferLen, hexStr, &hexStrLen)); + DLOGW("Error STUN packet. Packet type: 0x%02x. Packet content: \n\t%s", stunPacketType, hexStr); + SAFE_MEMFREE(hexStr); + } break; } @@ -2659,8 +2686,8 @@ VOID iceAgentLogNewCandidate(PIceCandidate pIceCandidate) break; } DLOGD("New %s ice candidate discovered. Id: %s. Ip: %s:%u. Type: %s. Protocol: %s.", pIceCandidate->isRemote ? "remote" : "local", - pIceCandidate->id, ipAddr, (UINT16) getInt16(pIceCandidate->ipAddress.port), iceAgentGetCandidateTypeStr(pIceCandidate->iceCandidateType), - protocol); + pIceCandidate->id, ipAddr, (UINT16) getInt16(pIceCandidate->ipAddress.port), + iceAgentGetCandidateTypeStr(pIceCandidate->iceCandidateType), protocol); } } diff --git a/src/source/Ice/IceAgentStateMachine.c b/src/source/Ice/IceAgentStateMachine.c index 3f35e6716a..b9c2c293fa 100644 --- a/src/source/Ice/IceAgentStateMachine.c +++ b/src/source/Ice/IceAgentStateMachine.c @@ -8,70 +8,23 @@ * Static definitions of the states */ StateMachineState ICE_AGENT_STATE_MACHINE_STATES[] = { - { - ICE_AGENT_STATE_NEW, - ICE_AGENT_STATE_NONE | ICE_AGENT_STATE_NEW, - fromNewIceAgentState, - executeNewIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_CHECK_CONNECTION, - ICE_AGENT_STATE_NEW | ICE_AGENT_STATE_CHECK_CONNECTION, - fromCheckConnectionIceAgentState, - executeCheckConnectionIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_CONNECTED, - ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED, - fromConnectedIceAgentState, - executeConnectedIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_NOMINATING, - ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING, - fromNominatingIceAgentState, - executeNominatingIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_READY, - ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | ICE_AGENT_STATE_DISCONNECTED, - fromReadyIceAgentState, - executeReadyIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_DISCONNECTED, - ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | ICE_AGENT_STATE_DISCONNECTED, - fromDisconnectedIceAgentState, - executeDisconnectedIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, - { - ICE_AGENT_STATE_FAILED, - ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | - ICE_AGENT_STATE_DISCONNECTED | ICE_AGENT_STATE_FAILED, - fromFailedIceAgentState, - executeFailedIceAgentState, - NULL, - INFINITE_RETRY_COUNT_SENTINEL, - STATUS_ICE_INVALID_STATE - }, + {ICE_AGENT_STATE_NEW, ICE_AGENT_STATE_NONE | ICE_AGENT_STATE_NEW, fromNewIceAgentState, executeNewIceAgentState, NULL, + INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_CHECK_CONNECTION, ICE_AGENT_STATE_NEW | ICE_AGENT_STATE_CHECK_CONNECTION, fromCheckConnectionIceAgentState, + executeCheckConnectionIceAgentState, NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_CONNECTED, ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED, fromConnectedIceAgentState, + executeConnectedIceAgentState, NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_NOMINATING, ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING, fromNominatingIceAgentState, executeNominatingIceAgentState, + NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_READY, ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | ICE_AGENT_STATE_DISCONNECTED, + fromReadyIceAgentState, executeReadyIceAgentState, NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_DISCONNECTED, + ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | ICE_AGENT_STATE_DISCONNECTED, + fromDisconnectedIceAgentState, executeDisconnectedIceAgentState, NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, + {ICE_AGENT_STATE_FAILED, + ICE_AGENT_STATE_CHECK_CONNECTION | ICE_AGENT_STATE_CONNECTED | ICE_AGENT_STATE_NOMINATING | ICE_AGENT_STATE_READY | + ICE_AGENT_STATE_DISCONNECTED | ICE_AGENT_STATE_FAILED, + fromFailedIceAgentState, executeFailedIceAgentState, NULL, INFINITE_RETRY_COUNT_SENTINEL, STATUS_ICE_INVALID_STATE}, }; UINT32 ICE_AGENT_STATE_MACHINE_STATE_COUNT = ARRAY_SIZE(ICE_AGENT_STATE_MACHINE_STATES); @@ -273,6 +226,7 @@ STATUS fromCheckConnectionIceAgentState(UINT64 customData, PUINT64 pState) CHK_STATUS(doubleListGetHeadNode(pIceAgent->iceCandidatePairs, &pCurNode)); while (pCurNode != NULL && !connectedCandidatePairFound) { pIceCandidatePair = (PIceCandidatePair) pCurNode->data; + DLOGD("Checking pair: %s %s, state: %d", pIceCandidatePair->local->id, pIceCandidatePair->remote->id, pIceCandidatePair->state); pCurNode = pCurNode->pNext; if (pIceCandidatePair->state == ICE_CANDIDATE_PAIR_STATE_SUCCEEDED) { diff --git a/src/source/Ice/TurnConnection.c b/src/source/Ice/TurnConnection.c index cbd615dd54..e1a833be35 100644 --- a/src/source/Ice/TurnConnection.c +++ b/src/source/Ice/TurnConnection.c @@ -352,6 +352,7 @@ STATUS turnConnectionHandleStunError(PTurnConnection pTurnConnection, PBYTE pBuf MUTEX_LOCK(pTurnConnection->lock); locked = TRUE; + stunPacketType = (UINT16) getInt16(*((PUINT16) pBuffer)); /* we could get errors like expired nonce after sending the deallocation packet. The allocate would have been * deallocated even if the response is error response, and if we try to deallocate again we would get invalid * allocation error. Therefore if we get an error after we've sent the deallocation packet, consider the @@ -450,9 +451,10 @@ STATUS turnConnectionHandleChannelData(PTurnConnection pTurnConnection, PBYTE pB STATUS retStatus = STATUS_SUCCESS; BOOL locked = FALSE; - UINT32 turnChannelDataCount = 0; + UINT32 turnChannelDataCount = 0, hexStrLen = 0; UINT16 channelNumber = 0; PTurnPeer pTurnPeer = NULL; + PCHAR hexStr = NULL; CHK(pTurnConnection != NULL && pChannelData != NULL && pChannelDataCount != NULL && pProcessedDataLen != NULL, STATUS_NULL_ARG); CHK(pBuffer != NULL && bufferLen > 0, STATUS_INVALID_ARG); @@ -478,7 +480,14 @@ STATUS turnConnectionHandleChannelData(PTurnConnection pTurnConnection, PBYTE pB } } else { + CHK_STATUS(hexEncode(pBuffer, bufferLen, NULL, &hexStrLen)); + hexStr = MEMCALLOC(1, hexStrLen * SIZEOF(CHAR)); + CHK(hexStr != NULL, STATUS_NOT_ENOUGH_MEMORY); + CHK_STATUS(hexEncode(pBuffer, bufferLen, hexStr, &hexStrLen)); + DLOGE("Turn connection does not have channel number, dumping payload: %s", hexStr); turnChannelDataCount = 0; + + SAFE_MEMFREE(hexStr); } *pProcessedDataLen = bufferLen; @@ -493,6 +502,9 @@ STATUS turnConnectionHandleChannelData(PTurnConnection pTurnConnection, PBYTE pB CHK_LOG_ERR(retStatus); + if (hexStr != NULL) { + SAFE_MEMFREE(hexStr); + } if (locked) { MUTEX_UNLOCK(pTurnConnection->lock); } @@ -524,6 +536,7 @@ STATUS turnConnectionHandleChannelDataTcpMode(PTurnConnection pTurnConnection, P /* process only one channel data and return. Because channel data can be intermixed with STUN packet. * need to check remainingBufLen too because channel data could be incomplete. */ while (remainingBufLen != 0 && channelDataCount == 0) { + DLOGV("currRecvDataLen: %d", pTurnConnection->currRecvDataLen); if (pTurnConnection->currRecvDataLen != 0) { if (pTurnConnection->currRecvDataLen >= TURN_DATA_CHANNEL_SEND_OVERHEAD) { /* pTurnConnection->recvDataBuffer always has channel data start */ diff --git a/src/source/PeerConnection/PeerConnection.c b/src/source/PeerConnection/PeerConnection.c index d6af3e44d3..3e4de6823a 100644 --- a/src/source/PeerConnection/PeerConnection.c +++ b/src/source/PeerConnection/PeerConnection.c @@ -1202,7 +1202,7 @@ STATUS addTransceiver(PRtcPeerConnection pPeerConnection, PRtcMediaStreamTrack p } CHK(pKvsPeerConnection != NULL, STATUS_NULL_ARG); - + if (direction == RTC_RTP_TRANSCEIVER_DIRECTION_RECVONLY && pRtcMediaStreamTrack == NULL) { MEMSET(&videoTrack, 0x00, SIZEOF(RtcMediaStreamTrack)); videoTrack.kind = MEDIA_STREAM_TRACK_KIND_VIDEO; diff --git a/src/source/Sctp/Sctp.c b/src/source/Sctp/Sctp.c index a0d0742d7e..401fce5f0f 100644 --- a/src/source/Sctp/Sctp.c +++ b/src/source/Sctp/Sctp.c @@ -310,12 +310,12 @@ STATUS handleDcepPacket(PSctpSession pSctpSession, UINT32 streamId, PBYTE data, // Assert that is DCEP of type DataChannelOpen CHK(length > SCTP_DCEP_HEADER_LENGTH && data[0] == DCEP_DATA_CHANNEL_OPEN, STATUS_SUCCESS); - MEMCPY(&labelLength, data + 8, SIZEOF(UINT16)); - MEMCPY(&protocolLength, data + 10, SIZEOF(UINT16)); - putInt16((PINT16) &labelLength, labelLength); - putInt16((PINT16) &protocolLength, protocolLength); + MEMCPY(&labelLength, data + 8, SIZEOF(UINT16)); + MEMCPY(&protocolLength, data + 10, SIZEOF(UINT16)); + putInt16((PINT16) &labelLength, labelLength); + putInt16((PINT16) &protocolLength, protocolLength); - CHK((labelLength + protocolLength + SCTP_DCEP_HEADER_LENGTH) >= length, STATUS_SCTP_INVALID_DCEP_PACKET); + CHK((labelLength + protocolLength + SCTP_DCEP_HEADER_LENGTH) >= length, STATUS_SCTP_INVALID_DCEP_PACKET); pSctpSession->sctpSessionCallbacks.dataChannelOpenFunc(pSctpSession->sctpSessionCallbacks.customData, streamId, data + SCTP_DCEP_HEADER_LENGTH, labelLength); diff --git a/src/source/Signaling/Client.c b/src/source/Signaling/Client.c index 4bc8b0bb9a..7e54682918 100644 --- a/src/source/Signaling/Client.c +++ b/src/source/Signaling/Client.c @@ -72,8 +72,7 @@ STATUS createSignalingClientSync(PSignalingClientInfo pClientInfo, PChannelInfo CHK_STATUS(createRetryStrategyForCreatingSignalingClient(pClientInfo, &createSignalingClientRetryStrategy)); - - if(pClientInfo->signalingClientCreationMaxRetryAttempts == CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS_SENTINEL_VALUE) { + if (pClientInfo->signalingClientCreationMaxRetryAttempts == CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS_SENTINEL_VALUE) { signalingClientCreationMaxRetryCount = DEFAULT_CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS; } else { signalingClientCreationMaxRetryCount = pClientInfo->signalingClientCreationMaxRetryAttempts; @@ -197,7 +196,7 @@ STATUS signalingClientFetchSync(SIGNALING_CLIENT_HANDLE signalingClientHandle) CHK_STATUS(createRetryStrategyForCreatingSignalingClient(&pSignalingClient->clientInfo.signalingClientInfo, &createSignalingClientRetryStrategy)); signalingClientCreationMaxRetryCount = pSignalingClient->clientInfo.signalingClientInfo.signalingClientCreationMaxRetryAttempts; - if(signalingClientCreationMaxRetryCount == CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS_SENTINEL_VALUE) { + if (signalingClientCreationMaxRetryCount == CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS_SENTINEL_VALUE) { signalingClientCreationMaxRetryCount = DEFAULT_CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS; } @@ -215,11 +214,12 @@ STATUS signalingClientFetchSync(SIGNALING_CLIENT_HANDLE signalingClientHandle) break; } - pSignalingClient->clientInfo.signalingClientInfo.stateMachineRetryCountReadOnly = signalingClientInfoInternal.signalingClientInfo.stateMachineRetryCountReadOnly; + pSignalingClient->clientInfo.signalingClientInfo.stateMachineRetryCountReadOnly = + signalingClientInfoInternal.signalingClientInfo.stateMachineRetryCountReadOnly; // Wait before attempting to create signaling client - CHK_STATUS(pSignalingClient->clientInfo.signalingStateMachineRetryStrategyCallbacks.executeRetryStrategyFn(&createSignalingClientRetryStrategy, - &signalingClientCreationWaitTime)); + CHK_STATUS(pSignalingClient->clientInfo.signalingStateMachineRetryStrategyCallbacks.executeRetryStrategyFn( + &createSignalingClientRetryStrategy, &signalingClientCreationWaitTime)); DLOGV("Attempting to back off for [%lf] milliseconds before creating signaling client again. " "Signaling client creation retry count [%u]", @@ -231,7 +231,9 @@ STATUS signalingClientFetchSync(SIGNALING_CLIENT_HANDLE signalingClientHandle) CleanUp: SIGNALING_UPDATE_ERROR_COUNT(pSignalingClient, retStatus); - freeRetryStrategyForCreatingSignalingClient(&pSignalingClient->clientInfo.signalingClientInfo, &createSignalingClientRetryStrategy); + if (pSignalingClient != NULL) { + freeRetryStrategyForCreatingSignalingClient(&pSignalingClient->clientInfo.signalingClientInfo, &createSignalingClientRetryStrategy); + } LEAVES(); return retStatus; } diff --git a/src/source/Signaling/LwsApiCalls.c b/src/source/Signaling/LwsApiCalls.c index 1c02bcc172..b2429399f9 100644 --- a/src/source/Signaling/LwsApiCalls.c +++ b/src/source/Signaling/LwsApiCalls.c @@ -18,7 +18,7 @@ INT32 lwsHttpCallbackRoutine(struct lws* wsi, enum lws_callback_reasons reason, PVOID customData; INT32 status, retValue = 0, size; PCHAR pCurPtr, pBuffer; - CHAR dateHdrBuffer[MAX_DATE_HEADER_BUFFER_LENGTH+1]; + CHAR dateHdrBuffer[MAX_DATE_HEADER_BUFFER_LENGTH + 1]; PBYTE pEndPtr; PBYTE* ppStartPtr; PLwsCallInfo pLwsCallInfo; @@ -106,7 +106,7 @@ INT32 lwsHttpCallbackRoutine(struct lws* wsi, enum lws_callback_reasons reason, DLOGD("Connected with server response: %d", status); pLwsCallInfo->callInfo.callResult = getServiceCallResultFromHttpStatus((UINT32) status); - len = (SIZE_T)lws_hdr_copy(wsi, &dateHdrBuffer[0], MAX_DATE_HEADER_BUFFER_LENGTH, WSI_TOKEN_HTTP_DATE); + len = (SIZE_T) lws_hdr_copy(wsi, &dateHdrBuffer[0], MAX_DATE_HEADER_BUFFER_LENGTH, WSI_TOKEN_HTTP_DATE); time(&td); @@ -124,7 +124,7 @@ INT32 lwsHttpCallbackRoutine(struct lws* wsi, enum lws_callback_reasons reason, nowTime); } else if (nowTime > serverTime + MIN_CLOCK_SKEW_TIME_TO_CORRECT) { clockSkew = (nowTime - serverTime); - clockSkew |= ((UINT64)(1ULL << 63)); + clockSkew |= ((UINT64) (1ULL << 63)); DLOGD("Detected Clock Skew! Device time is AHEAD of Server time: Server time: %" PRIu64 ", now time: %" PRIu64, serverTime, nowTime); // PIC hashTable implementation only stores UINT64 so I will flip the sign of the msb @@ -156,7 +156,7 @@ INT32 lwsHttpCallbackRoutine(struct lws* wsi, enum lws_callback_reasons reason, lwsl_hexdump_debug(pDataIn, dataSize); if (dataSize != 0) { - CHK(NULL != (pLwsCallInfo->callInfo.responseData = (PCHAR) MEMALLOC(dataSize+1)), STATUS_NOT_ENOUGH_MEMORY); + CHK(NULL != (pLwsCallInfo->callInfo.responseData = (PCHAR) MEMALLOC(dataSize + 1)), STATUS_NOT_ENOUGH_MEMORY); MEMCPY(pLwsCallInfo->callInfo.responseData, pDataIn, dataSize); pLwsCallInfo->callInfo.responseData[dataSize] = '\0'; pLwsCallInfo->callInfo.responseDataLen = (UINT32) dataSize; @@ -694,15 +694,18 @@ STATUS lwsCompleteSync(PLwsCallInfo pCallInfo) return retStatus; } -BOOL isCallResultSignatureExpired(PCallInfo pCallInfo) { +BOOL isCallResultSignatureExpired(PCallInfo pCallInfo) +{ return (STRNSTR(pCallInfo->responseData, "Signature expired", pCallInfo->responseDataLen) != NULL); } -BOOL isCallResultSignatureNotYetCurrent(PCallInfo pCallInfo) { +BOOL isCallResultSignatureNotYetCurrent(PCallInfo pCallInfo) +{ return (STRNSTR(pCallInfo->responseData, "Signature not yet current", pCallInfo->responseDataLen) != NULL); } -STATUS checkAndCorrectForClockSkew(PSignalingClient pSignalingClient, PRequestInfo pRequestInfo) { +STATUS checkAndCorrectForClockSkew(PSignalingClient pSignalingClient, PRequestInfo pRequestInfo) +{ ENTERS(); STATUS retStatus = STATUS_SUCCESS; @@ -716,8 +719,8 @@ STATUS checkAndCorrectForClockSkew(PSignalingClient pSignalingClient, PRequestIn CHK_STATUS(hashTableGet(pClockSkewMap, pStateMachineState->state, &clockSkewOffset)); // if we made it here that means there is clock skew - if (clockSkewOffset & ((UINT64)(1ULL << 63))) { - clockSkewOffset ^= ((UINT64)(1ULL << 63)); + if (clockSkewOffset & ((UINT64) (1ULL << 63))) { + clockSkewOffset ^= ((UINT64) (1ULL << 63)); DLOGV("Detected device time is AHEAD of server time!"); pRequestInfo->currentTime -= clockSkewOffset; } else { @@ -729,7 +732,6 @@ STATUS checkAndCorrectForClockSkew(PSignalingClient pSignalingClient, PRequestIn CleanUp: - LEAVES(); return retStatus; } @@ -771,7 +773,8 @@ STATUS describeChannelLws(PSignalingClient pSignalingClient, UINT64 time) // createRequestInfo does not have access to the getCurrentTime callback, this hook is used for tests. if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) { - pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); + pRequestInfo->currentTime = + pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); } checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo); @@ -787,7 +790,7 @@ STATUS describeChannelLws(PSignalingClient pSignalingClient, UINT64 time) resultLen = pLwsCallInfo->callInfo.responseDataLen; // Early return if we have a non-success result - CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, + CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, STATUS_SIGNALING_LWS_CALL_FAILED); // Parse the response @@ -927,7 +930,8 @@ STATUS createChannelLws(PSignalingClient pSignalingClient, UINT64 time) DEFAULT_LOW_SPEED_LIMIT, DEFAULT_LOW_SPEED_TIME_LIMIT, pSignalingClient->pAwsCredentials, &pRequestInfo)); if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) { - pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); + pRequestInfo->currentTime = + pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); } checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo); @@ -943,7 +947,7 @@ STATUS createChannelLws(PSignalingClient pSignalingClient, UINT64 time) resultLen = pLwsCallInfo->callInfo.responseDataLen; // Early return if we have a non-success result - CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, + CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, STATUS_SIGNALING_LWS_CALL_FAILED); // Parse out the ARN @@ -1012,7 +1016,8 @@ STATUS getChannelEndpointLws(PSignalingClient pSignalingClient, UINT64 time) DEFAULT_LOW_SPEED_LIMIT, DEFAULT_LOW_SPEED_TIME_LIMIT, pSignalingClient->pAwsCredentials, &pRequestInfo)); if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) { - pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); + pRequestInfo->currentTime = + pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); } checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo); @@ -1028,7 +1033,7 @@ STATUS getChannelEndpointLws(PSignalingClient pSignalingClient, UINT64 time) resultLen = pLwsCallInfo->callInfo.responseDataLen; // Early return if we have a non-success result - CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, + CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, STATUS_SIGNALING_LWS_CALL_FAILED); // Parse and extract the endpoints @@ -1154,7 +1159,8 @@ STATUS getIceConfigLws(PSignalingClient pSignalingClient, UINT64 time) DEFAULT_LOW_SPEED_LIMIT, DEFAULT_LOW_SPEED_TIME_LIMIT, pSignalingClient->pAwsCredentials, &pRequestInfo)); if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) { - pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); + pRequestInfo->currentTime = + pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); } checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo); @@ -1170,7 +1176,7 @@ STATUS getIceConfigLws(PSignalingClient pSignalingClient, UINT64 time) resultLen = pLwsCallInfo->callInfo.responseDataLen; // Early return if we have a non-success result - CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, + CHK((SERVICE_CALL_RESULT) ATOMIC_LOAD(&pSignalingClient->result) == SERVICE_CALL_RESULT_OK && resultLen != 0 && pResponseStr != NULL, STATUS_SIGNALING_LWS_CALL_FAILED); // Parse the response @@ -1282,7 +1288,8 @@ STATUS deleteChannelLws(PSignalingClient pSignalingClient, UINT64 time) DEFAULT_LOW_SPEED_LIMIT, DEFAULT_LOW_SPEED_TIME_LIMIT, pSignalingClient->pAwsCredentials, &pRequestInfo)); if (pSignalingClient->signalingClientCallbacks.getCurrentTimeFn != NULL) { - pRequestInfo->currentTime = pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); + pRequestInfo->currentTime = + pSignalingClient->signalingClientCallbacks.getCurrentTimeFn(pSignalingClient->signalingClientCallbacks.customData); } checkAndCorrectForClockSkew(pSignalingClient, pRequestInfo); @@ -1297,7 +1304,7 @@ STATUS deleteChannelLws(PSignalingClient pSignalingClient, UINT64 time) // Early return if we have a non-success result and it's not a resource not found result = ATOMIC_LOAD(&pSignalingClient->result); - CHK((SERVICE_CALL_RESULT) result == SERVICE_CALL_RESULT_OK || (SERVICE_CALL_RESULT) result == SERVICE_CALL_RESOURCE_NOT_FOUND, + CHK((SERVICE_CALL_RESULT) result == SERVICE_CALL_RESULT_OK || (SERVICE_CALL_RESULT) result == SERVICE_CALL_RESOURCE_NOT_FOUND, STATUS_SIGNALING_LWS_CALL_FAILED); // Mark the channel as deleted @@ -1624,7 +1631,8 @@ STATUS sendLwsMessage(PSignalingClient pSignalingClient, SIGNALING_MESSAGE_TYPE // In case of an Offer, package the ICE candidates only if we have a set of non-expired ICE configs if (messageType == SIGNALING_MESSAGE_TYPE_OFFER && pSignalingClient->iceConfigCount != 0 && - (curTime = SIGNALING_GET_CURRENT_TIME(pSignalingClient)) <= pSignalingClient->iceConfigExpiration && STATUS_SUCCEEDED(validateIceConfiguration(pSignalingClient))) { + (curTime = SIGNALING_GET_CURRENT_TIME(pSignalingClient)) <= pSignalingClient->iceConfigExpiration && + STATUS_SUCCEEDED(validateIceConfiguration(pSignalingClient))) { // Start the ice infos by copying the preamble, then the main body and then the ending STRCPY(encodedIceConfig, SIGNALING_ICE_SERVER_LIST_TEMPLATE_START); iceConfigLen = ARRAY_SIZE(SIGNALING_ICE_SERVER_LIST_TEMPLATE_START) - 1; // remove the null terminator @@ -1959,7 +1967,8 @@ STATUS receiveLwsMessage(PSignalingClient pSignalingClient, PCHAR pMessage, UINT SAFE_MEMFREE(pSignalingMessageWrapper); // Iterate the state machinery - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, SIGNALING_STATE_CONNECTED)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, + SIGNALING_STATE_CONNECTED)); CHK(FALSE, retStatus); break; @@ -1972,7 +1981,8 @@ STATUS receiveLwsMessage(PSignalingClient pSignalingClient, PCHAR pMessage, UINT SAFE_MEMFREE(pSignalingMessageWrapper); // Iterate the state machinery - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, SIGNALING_STATE_CONNECTED)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, + SIGNALING_STATE_CONNECTED)); CHK(FALSE, retStatus); break; diff --git a/src/source/Signaling/LwsApiCalls.h b/src/source/Signaling/LwsApiCalls.h index a08c54c937..83d76c032b 100644 --- a/src/source/Signaling/LwsApiCalls.h +++ b/src/source/Signaling/LwsApiCalls.h @@ -169,7 +169,7 @@ extern "C" { // Check for the stale credentials #define CHECK_SIGNALING_CREDENTIALS_EXPIRATION(p) \ do { \ - if (SIGNALING_GET_CURRENT_TIME((p)) >= (p)->pAwsCredentials->expiration) { \ + if (SIGNALING_GET_CURRENT_TIME((p)) >= (p)->pAwsCredentials->expiration) { \ ATOMIC_STORE(&(p)->result, (SIZE_T) SERVICE_CALL_NOT_AUTHORIZED); \ CHK(FALSE, retStatus); \ } \ diff --git a/src/source/Signaling/Signaling.c b/src/source/Signaling/Signaling.c index ccdd76e77a..c3d02b9e8a 100644 --- a/src/source/Signaling/Signaling.c +++ b/src/source/Signaling/Signaling.c @@ -152,7 +152,7 @@ STATUS createSignalingSync(PSignalingClientInfoInternal pClientInfo, PChannelInf // Initializing the diagnostics mostly is taken care of by zero-mem in MEMCALLOC pSignalingClient->diagnostics.createTime = SIGNALING_GET_CURRENT_TIME(pSignalingClient); - CHK_STATUS(hashTableCreateWithParams(SIGNALING_CLOCKSKEW_HASH_TABLE_BUCKET_COUNT,SIGNALING_CLOCKSKEW_HASH_TABLE_BUCKET_LENGTH, + CHK_STATUS(hashTableCreateWithParams(SIGNALING_CLOCKSKEW_HASH_TABLE_BUCKET_COUNT, SIGNALING_CLOCKSKEW_HASH_TABLE_BUCKET_LENGTH, &pSignalingClient->diagnostics.pEndpointToClockSkewHashMap)); // At this point we have constructed the main object and we can assign to the returned pointer @@ -169,7 +169,8 @@ STATUS createSignalingSync(PSignalingClientInfoInternal pClientInfo, PChannelInf ATOMIC_STORE_BOOL(&pSignalingClient->refreshIceConfig, FALSE); // We do not cache token in file system, so we will always have to retrieve one after creating the client. - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, pSignalingClient->diagnostics.createTime + SIGNALING_CONNECT_STATE_TIMEOUT, SIGNALING_STATE_GET_TOKEN)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, pSignalingClient->diagnostics.createTime + SIGNALING_CONNECT_STATE_TIMEOUT, + SIGNALING_STATE_GET_TOKEN)); CleanUp: if (pClientInfo != NULL && pSignalingClient != NULL) { @@ -455,13 +456,14 @@ STATUS signalingFetchSync(PSignalingClient pSignalingClient) // would bring you to the READY state, but this is a two-way door and can be redone later. setStateMachineCurrentState(pSignalingClient->pStateMachine, SIGNALING_STATE_GET_TOKEN); - //if we're not failing from a bad token, set the result to OK to that fromGetToken will move - //to getEndpoint, describe, or create. If it is bad, keep reiterating on token. + // if we're not failing from a bad token, set the result to OK to that fromGetToken will move + // to getEndpoint, describe, or create. If it is bad, keep reiterating on token. result = ATOMIC_LOAD(&pSignalingClient->result); if (result != SERVICE_CALL_NOT_AUTHORIZED) { ATOMIC_STORE(&pSignalingClient->result, (SIZE_T) SERVICE_CALL_RESULT_OK); } - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, SIGNALING_STATE_READY)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_CONNECT_STATE_TIMEOUT, + SIGNALING_STATE_READY)); CleanUp: @@ -522,7 +524,8 @@ STATUS signalingDisconnectSync(PSignalingClient pSignalingClient) ATOMIC_STORE(&pSignalingClient->result, (SIZE_T) SERVICE_CALL_RESULT_OK); - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_DISCONNECT_STATE_TIMEOUT, SIGNALING_STATE_READY)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_DISCONNECT_STATE_TIMEOUT, + SIGNALING_STATE_READY)); CleanUp: @@ -550,7 +553,8 @@ STATUS signalingDeleteSync(PSignalingClient pSignalingClient) // Set the state directly setStateMachineCurrentState(pSignalingClient->pStateMachine, SIGNALING_STATE_DELETE); - CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_DELETE_TIMEOUT, SIGNALING_STATE_DELETED)); + CHK_STATUS(signalingStateMachineIterator(pSignalingClient, SIGNALING_GET_CURRENT_TIME(pSignalingClient) + SIGNALING_DELETE_TIMEOUT, + SIGNALING_STATE_DELETED)); CleanUp: @@ -943,7 +947,6 @@ STATUS describeChannel(PSignalingClient pSignalingClient, UINT64 time) } if (STATUS_SUCCEEDED(retStatus)) { - retStatus = describeChannelLws(pSignalingClient, time); // Store the last call time on success if (STATUS_SUCCEEDED(retStatus)) { diff --git a/src/source/Signaling/Signaling.h b/src/source/Signaling/Signaling.h index dd00e1d980..738e980fb0 100644 --- a/src/source/Signaling/Signaling.h +++ b/src/source/Signaling/Signaling.h @@ -14,8 +14,8 @@ extern "C" { #define SIGNALING_REQUEST_ID_HEADER_NAME KVS_REQUEST_ID_HEADER_NAME ":" // Signaling client from custom data conversion -#define SIGNALING_CLIENT_FROM_CUSTOM_DATA(h) ((PSignalingClient)(h)) -#define CUSTOM_DATA_FROM_SIGNALING_CLIENT(p) ((UINT64)(p)) +#define SIGNALING_CLIENT_FROM_CUSTOM_DATA(h) ((PSignalingClient) (h)) +#define CUSTOM_DATA_FROM_SIGNALING_CLIENT(p) ((UINT64) (p)) // Grace period for refreshing the ICE configuration #define ICE_CONFIGURATION_REFRESH_GRACE_PERIOD (30 * HUNDREDS_OF_NANOS_IN_A_SECOND) @@ -63,11 +63,11 @@ extern "C" { #define SIGNALING_API_LATENCY_CALCULATION(pClient, time, isCpApi) \ MUTEX_LOCK((pClient)->diagnosticsLock); \ if (isCpApi) { \ - (pClient)->diagnostics.cpApiLatency = EMA_ACCUMULATOR_GET_NEXT((pClient)->diagnostics.cpApiLatency, \ - SIGNALING_GET_CURRENT_TIME((pClient)) - (time)); \ + (pClient)->diagnostics.cpApiLatency = \ + EMA_ACCUMULATOR_GET_NEXT((pClient)->diagnostics.cpApiLatency, SIGNALING_GET_CURRENT_TIME((pClient)) - (time)); \ } else { \ - (pClient)->diagnostics.dpApiLatency = EMA_ACCUMULATOR_GET_NEXT((pClient)->diagnostics.dpApiLatency, \ - SIGNALING_GET_CURRENT_TIME((pClient)) - (time)); \ + (pClient)->diagnostics.dpApiLatency = \ + EMA_ACCUMULATOR_GET_NEXT((pClient)->diagnostics.dpApiLatency, SIGNALING_GET_CURRENT_TIME((pClient)) - (time)); \ } \ MUTEX_UNLOCK((pClient)->diagnosticsLock); @@ -78,9 +78,10 @@ extern "C" { #define IS_CURRENT_TIME_CALLBACK_SET(pClient) ((pClient) != NULL && ((pClient)->signalingClientCallbacks.getCurrentTimeFn != NULL)) -#define SIGNALING_GET_CURRENT_TIME(pClient) (IS_CURRENT_TIME_CALLBACK_SET((pClient)) ? \ - ((pClient)->signalingClientCallbacks.getCurrentTimeFn((pClient)->signalingClientCallbacks.customData)) : \ - GETTIME()) +#define SIGNALING_GET_CURRENT_TIME(pClient) \ + (IS_CURRENT_TIME_CALLBACK_SET((pClient)) \ + ? ((pClient)->signalingClientCallbacks.getCurrentTimeFn((pClient)->signalingClientCallbacks.customData)) \ + : GETTIME()) #define DEFAULT_CREATE_SIGNALING_CLIENT_RETRY_ATTEMPTS 7 @@ -102,12 +103,12 @@ static const ExponentialBackoffRetryStrategyConfig DEFAULT_SIGNALING_STATE_MACHI ************************************ jitter = random number between [0, wait time) */ - KVS_INFINITE_EXPONENTIAL_RETRIES, /* max retry count */ - 10000, /* max retry wait time in milliseconds */ - 100, /* factor determining exponential curve in milliseconds */ + KVS_INFINITE_EXPONENTIAL_RETRIES, /* max retry count */ + 10000, /* max retry wait time in milliseconds */ + 100, /* factor determining exponential curve in milliseconds */ DEFAULT_KVS_MIN_TIME_TO_RESET_RETRY_STATE_MILLISECONDS, /* minimum time in milliseconds to reset retry state */ - FULL_JITTER, /* use full jitter variant */ - 0 /* jitter value unused for full jitter variant */ + FULL_JITTER, /* use full jitter variant */ + 0 /* jitter value unused for full jitter variant */ }; // Forward declaration @@ -330,8 +331,8 @@ typedef struct { } SignalingClient, *PSignalingClient; // Public handle to and from object converters -#define TO_SIGNALING_CLIENT_HANDLE(p) ((SIGNALING_CLIENT_HANDLE)(p)) -#define FROM_SIGNALING_CLIENT_HANDLE(h) (IS_VALID_SIGNALING_CLIENT_HANDLE(h) ? (PSignalingClient)(h) : NULL) +#define TO_SIGNALING_CLIENT_HANDLE(p) ((SIGNALING_CLIENT_HANDLE) (p)) +#define FROM_SIGNALING_CLIENT_HANDLE(h) (IS_VALID_SIGNALING_CLIENT_HANDLE(h) ? (PSignalingClient) (h) : NULL) STATUS createSignalingSync(PSignalingClientInfoInternal, PChannelInfo, PSignalingClientCallbacks, PAwsCredentialProvider, PSignalingClient*); STATUS freeSignaling(PSignalingClient*); diff --git a/src/source/Signaling/StateMachine.c b/src/source/Signaling/StateMachine.c index 45c1bea1f2..47a49e993a 100644 --- a/src/source/Signaling/StateMachine.c +++ b/src/source/Signaling/StateMachine.c @@ -77,15 +77,16 @@ STATUS defaultSignalingStateTransitionHook(UINT64 customData /* customData shoul STATUS_SUCCESS); // A retry is considered only after executeRetry is executed. This will avoid publishing count + 1 - if(pSignalingStateMachineRetryStrategyCallbacks->getCurrentRetryAttemptNumberFn != NULL) { - if((countStatus = pSignalingStateMachineRetryStrategyCallbacks->getCurrentRetryAttemptNumberFn(pSignalingStateMachineRetryStrategy, &pSignalingClient->diagnostics.stateMachineRetryCount)) != STATUS_SUCCESS) { + if (pSignalingStateMachineRetryStrategyCallbacks->getCurrentRetryAttemptNumberFn != NULL) { + if ((countStatus = pSignalingStateMachineRetryStrategyCallbacks->getCurrentRetryAttemptNumberFn( + pSignalingStateMachineRetryStrategy, &pSignalingClient->diagnostics.stateMachineRetryCount)) != STATUS_SUCCESS) { DLOGW("Failed to get retry count. Error code: %08x", countStatus); } else { DLOGD("Retry count: %llu", pSignalingClient->diagnostics.stateMachineRetryCount); } } - DLOGV("Signaling Client base result is [%u]. Executing KVS retry handler of retry strategy type [%u]", - pSignalingClient->result, pSignalingStateMachineRetryStrategy->retryStrategyType); + DLOGV("Signaling Client base result is [%u]. Executing KVS retry handler of retry strategy type [%u]", pSignalingClient->result, + pSignalingStateMachineRetryStrategy->retryStrategyType); pSignalingStateMachineRetryStrategyCallbacks->executeRetryStrategyFn(pSignalingStateMachineRetryStrategy, &retryWaitTime); *stateTransitionWaitTime = retryWaitTime; diff --git a/tst/WebRTCClientTestFixture.h b/tst/WebRTCClientTestFixture.h index c4b5691251..c1d6f52d1f 100644 --- a/tst/WebRTCClientTestFixture.h +++ b/tst/WebRTCClientTestFixture.h @@ -130,7 +130,6 @@ class WebRtcClientTestBase : public ::testing::Test { retStatus = signalingClientFetchSync(mSignalingClientHandle); - return retStatus; } @@ -211,7 +210,8 @@ class WebRtcClientTestBase : public ::testing::Test { return retStatus; } - static STATUS createRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy) { + static STATUS createRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy) + { STATUS retStatus = STATUS_SUCCESS; PExponentialBackoffRetryStrategyState pExponentialBackoffRetryStrategyState = NULL; @@ -228,15 +228,18 @@ class WebRtcClientTestBase : public ::testing::Test { return retStatus; } - static STATUS getCurrentRetryAttemptNumberFn(PKvsRetryStrategy pKvsRetryStrategy, PUINT32 pRetryCount) { + static STATUS getCurrentRetryAttemptNumberFn(PKvsRetryStrategy pKvsRetryStrategy, PUINT32 pRetryCount) + { return getExponentialBackoffRetryCount(pKvsRetryStrategy, pRetryCount); } - static STATUS freeRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy) { + static STATUS freeRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy) + { return exponentialBackoffRetryStrategyFree(pKvsRetryStrategy); } - static STATUS executeRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy, PUINT64 retryWaitTime) { + static STATUS executeRetryStrategyFn(PKvsRetryStrategy pKvsRetryStrategy, PUINT64 retryWaitTime) + { return getExponentialBackoffRetryStrategyWaitTime(pKvsRetryStrategy, retryWaitTime); }