Compare commits

...

110 Commits

Author SHA1 Message Date
tyranron
e825110d38
Update Alpine to 3.21.1 version in Docker image
Some checks failed
Docker / build (arm32v7, alpine) (push) Has been cancelled
Docker / build (arm32v7, debian) (push) Has been cancelled
Docker / build (arm64v8, alpine) (push) Has been cancelled
Docker / build (arm64v8, debian) (push) Has been cancelled
Docker / build (i386, alpine) (push) Has been cancelled
Docker / build (i386, debian) (push) Has been cancelled
Docker / build (ppc64le, alpine) (push) Has been cancelled
Docker / build (ppc64le, debian) (push) Has been cancelled
Docker / build (s390x, alpine) (push) Has been cancelled
Docker / build (s390x, debian) (push) Has been cancelled
Docker / test (amd64, alpine) (push) Has been cancelled
Docker / test (amd64, debian) (push) Has been cancelled
Docker / test (arm32v6, alpine) (push) Has been cancelled
Docker / test (arm32v6, debian) (push) Has been cancelled
Docker / test (arm32v7, alpine) (push) Has been cancelled
Docker / test (arm32v7, debian) (push) Has been cancelled
Docker / test (arm64v8, alpine) (push) Has been cancelled
Docker / test (arm64v8, debian) (push) Has been cancelled
Docker / test (i386, alpine) (push) Has been cancelled
Docker / test (i386, debian) (push) Has been cancelled
Docker / test (ppc64le, alpine) (push) Has been cancelled
Docker / test (ppc64le, debian) (push) Has been cancelled
Docker / test (s390x, debian) (push) Has been cancelled
Docker / push (alpine, docker.io) (push) Has been cancelled
Docker / push (alpine, ghcr.io) (push) Has been cancelled
Docker / push (alpine, quay.io) (push) Has been cancelled
Docker / push (debian, docker.io) (push) Has been cancelled
Docker / push (debian, ghcr.io) (push) Has been cancelled
Docker / push (debian, quay.io) (push) Has been cancelled
Docker / release (GitHub) (push) Has been cancelled
2025-01-08 13:02:43 +02:00
guoyingbo
22aae5d0d0
Windows '_WTA' bug (#1624)
Every time the '_WTA' is called, its initial value is null, so the
function returns directly.


c98bb93514/src/apps/common/apputils.c (L905-L908)

c98bb93514/src/apps/common/apputils.c (L939-L941)

c98bb93514/src/apps/common/apputils.c (L960-L962)

c98bb93514/src/apps/common/apputils.c (L981-L983)
2025-01-04 17:50:29 -08:00
Pavel Punsky
c98bb93514
Fix cmake issues detecting mongo and libsystemd on macOS (#1621)
- libsystemd does not exist on macOS - ignore it and reduce warnings
during cmake step
- mongo-c has cmake file on macOS - reusing the same code path and
reduce warnings
2024-12-27 14:52:44 -08:00
Pavel Punsky
58f1b8926c
Fix hiredis detection by cmake (#1620)
See #1618 for details

This fix allows proper hiredis detection on macOS when building with
cmake
2024-12-27 11:36:58 -08:00
tyranron
326b983ece
Update Debian "bookworm" to 20241223 snapshot in Docker image 2024-12-25 11:08:34 +02:00
Pavel Punsky
89a5600be1
Drop TLS version support detection (#1617)
With requiring openssl version at least 1.1.1 all versions of TLS (up to
and including 1.3) and DTLS 1.2 are supported
With that, no detection or ability to disable a version will be provided
2024-12-19 17:10:49 -08:00
Pavel Punsky
20da9cd09a
Cleanup ALPN_SUPPORTED define usage (#1616)
As of openssl 1.1.1 ALPN is supported - no need for all the ifdefs anymore
2024-12-19 16:41:45 -08:00
Pavel Punsky
9f779a64d0
Fix warnings type conversion (#1615) 2024-12-19 09:05:37 -08:00
Alex Gustafsson
790cc6f79e
Add parameter for specifying prometheus path (#1602)
Add a `--prometheus-path` parameter which allows users to specify at
what
path the metrics should be exposed.

This simplifies serving metrics on a specific path behind some
restrictive reverse proxies that expect the upstream server to serve
URLs with paths matching the requested path.

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-12-18 14:50:38 -08:00
Pavel Punsky
3370eaf12d
Do not build with Ubuntu 18, use 24 (#1613)
Re-delete file that was undeleted accidentally
2024-12-15 17:37:03 -08:00
Michael Jones
c9878469fc
[BREAKING] Remove support for openssl older than 1.1.1 (#1397)
Openssl 1.1.1 is end-of-life in September 2023.
This PR removes support for versions of openssl OLDER than 1.1.1
1.1.1 should still be usable after this change is merged.

I don't see any value in supporting 1.1.1, but didn't see a reason to
purge support for 1.1.1 when there are so few checks for >= 3.0.

Note that this does also remove CI support for Ubuntu 16.04. The
official version of OpenSSL from Ubuntu for this release is listed here:
https://launchpad.net/ubuntu/+source/openssl as 1.0.2g

Since no newer releases of coturn will be backported by Canonical to
Ubuntu 16.04, anyone using Coturn on this operating system will have to
download and compile it themselves. They may build their own version of
OpenSSL if they somehow cannot upgrade to a newer version of Ubuntu.

My position is that these users should prefer to upgrade to a newer
operating system than worry about chasing newer releases of Coturn.

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-12-13 13:06:24 -08:00
Pavel Punsky
ea280f9431
[BREAKING] Cleanup deprecated options (#1599)
Following configuration options deleted:
- `--secret-ts-exp-time`
- `--prod` - disables SOFTWARE_ATTRIBUTE in messages. Now it is default.
To enable SOFTWARE_ATTRIBUTE use `--software-attribute`
- `--no-sslv2`, `--no-sslv3` - old versions of SSL are not supported and
it is not possible to enable them

These are breaking changes - if the CLI command has any of those
arguments it will cause turnserver to terminate and notify about unknown
argument
2024-12-13 09:31:06 -08:00
Pavel Punsky
94fcfadce1
[BREAKING] Reverse SOFTWARE_ATTRIBUTE_OPT to avoid inverse logic (#1598)
As part of looking at #1588 , I figured that sending `SOFTWARE`
attribute is also part of a problem as it increases messages sent out by
coturn and thus increasing amplification factor. For 4.6.2, the
additional size is 24 bytes (4 bytes attribute header, and 20 bytes for
"Coturn-4.6.2 'Gorst'")

If we are to use an example from #1588, "A 62 byte request will be met
with Coturn’s 401 Unauthorized response which is 150 bytes, a factor of
~2.42." - without SOFTWARE the response will be 126 bytes which reduces
amplification factor to ~2.

As I observed with multiple providers using coturn - some of the are
sending it. Meaning, they do not set `--no-software-attribute` - most
probably due to lack of clarity about this setting.

I believe sending SOFTWARE_ATTRIBUTE should be off by default which is
hinted in the RFC
(https://datatracker.ietf.org/doc/html/rfc8489#section-16.1.2)

Detailed changes:
- Extract setting the attribute into a function to avoid code
duplication
- This option is now not reloadable
- The option is now called `software_attribute` because inverse logic
creates multiple double-not in the code which makes it harder to read.
- `no-software_attribute` is still functional but marked as deprecated
in documentation

Test Plan:
- Run local tests with different cli arguments (new and deprecated) and
confirm SOFTWARE attribute is off by default, and added when arguments
say so
2024-12-13 09:28:45 -08:00
tyranron
a6b052c570
Upgrade Docker image to 4.6.3 Coturn version
Some checks failed
Docker / build (arm32v7, alpine) (push) Has been cancelled
Docker / build (arm32v7, debian) (push) Has been cancelled
Docker / build (arm64v8, alpine) (push) Has been cancelled
Docker / build (arm64v8, debian) (push) Has been cancelled
Docker / build (i386, alpine) (push) Has been cancelled
Docker / build (i386, debian) (push) Has been cancelled
Docker / build (ppc64le, alpine) (push) Has been cancelled
Docker / build (ppc64le, debian) (push) Has been cancelled
Docker / build (s390x, alpine) (push) Has been cancelled
Docker / build (s390x, debian) (push) Has been cancelled
Docker / test (amd64, alpine) (push) Has been cancelled
Docker / test (amd64, debian) (push) Has been cancelled
Docker / test (arm32v6, alpine) (push) Has been cancelled
Docker / test (arm32v6, debian) (push) Has been cancelled
Docker / test (arm32v7, alpine) (push) Has been cancelled
Docker / test (arm32v7, debian) (push) Has been cancelled
Docker / test (arm64v8, alpine) (push) Has been cancelled
Docker / test (arm64v8, debian) (push) Has been cancelled
Docker / test (i386, alpine) (push) Has been cancelled
Docker / test (i386, debian) (push) Has been cancelled
Docker / test (ppc64le, alpine) (push) Has been cancelled
Docker / test (ppc64le, debian) (push) Has been cancelled
Docker / test (s390x, debian) (push) Has been cancelled
Docker / push (alpine, docker.io) (push) Has been cancelled
Docker / push (alpine, ghcr.io) (push) Has been cancelled
Docker / push (alpine, quay.io) (push) Has been cancelled
Docker / push (debian, docker.io) (push) Has been cancelled
Docker / push (debian, ghcr.io) (push) Has been cancelled
Docker / push (debian, quay.io) (push) Has been cancelled
Docker / release (GitHub) (push) Has been cancelled
2024-12-11 19:33:47 +01:00
Kai Ren
adae3dda3e
Refactor CI workflows and fix failures due to Node.js 20 (#1610, actions/checkout#1809) 2024-12-11 19:27:05 +01:00
Pavel Punsky
b6e53ca4c9
Update version to 4.6.3 (#1609)
Some checks failed
AmazonLinux2023 / builds (amazonlinux:2023) (push) Has been cancelled
AmazonLinux2 / builds (amazonlinux:2) (push) Has been cancelled
Lint / build (push) Has been cancelled
clang-tidy / clang-tidy (Release) (push) Has been cancelled
CMake / build (push) Has been cancelled
CodeQL / CodeQL Analyze (push) Has been cancelled
compiler-sanitizers / compiler-sanitizers (address,pointer-compare,pointer-subtract) (push) Has been cancelled
compiler-sanitizers / compiler-sanitizers (thread) (push) Has been cancelled
MacOS / builds (macos-12) (push) Has been cancelled
MacOS / builds (macos-13) (push) Has been cancelled
MacOS / builds (macos-14) (push) Has been cancelled
mingw / build (OFF, Debug, windows-latest) (push) Has been cancelled
mingw / build (OFF, Release, windows-latest) (push) Has been cancelled
msvc-analyzer / msvc-analyzer (OFF, Release, x64, v143) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Ubuntu / builds (ubuntu:16.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:18.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:20.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:22.04) (push) Has been cancelled
preparing for new tag 4.6.3

---------

Co-authored-by: tyranron <tyranron@gmail.com>
2024-12-11 10:13:38 -08:00
Pavel Punsky
329cda4715
Fix cmake and prometheus test build jobs (#1608)
Some actions do not build with prometheus - adding prometheus tests
fails the jobs
cmake build tests did not run due to different target folder (while
reporting success) - now the bin folder is detected
2024-12-10 19:38:39 -08:00
Alex Gustafsson
d63704c72d
Implement custom prometheus http handler (#1591)
Implement a custom prometheus http handler in order to:

1. Support listening on a specified address as opposed to any
2. Remove the requirement on the unmaintained promhttp library

This feature comes with one limitation: if an IPv4 address is used, the
server will not listen on the IPv6-mapped address, even if IPv6 is
available. That is, dual-stacking does not work.

Solves: #1475

---------

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-12-10 10:28:43 -08:00
tyranron
8f9c87075b
Upgrade Alpine to 3.21 version in Docker image
Some checks failed
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Ubuntu / builds (ubuntu:16.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:18.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:20.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:22.04) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-12-06 19:10:33 +01:00
tyranron
817bbd1bea
Update Debian "bookworm" to 20241202 snapshot in Docker image 2024-12-05 12:28:33 +01:00
Robert Silén
f6004a1c18
Add MariaDB support to README.md (#1601)
Suggesting to add MariaDB to README - any reason not to?
2024-11-21 14:13:36 -08:00
maddy
c4a954a7fc
Allow authenticating with a username to redis (#1488)
Add ability to authenticate to redis with a password (and optionally username for redis 6.0)

Tested by building and using with redis on old and new versionss
2024-11-18 16:51:02 -08:00
hariprasadt
e5ffe6e0a3
Easy installation of coturn on AWS (#1581)
https://github.com/coturn/coturn/issues/1576

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-11-18 09:00:08 -08:00
Chai-Shi
268f811f9e
Add prometheus setting suggestions on turn.conf in example folder (#1597)
I believe that many users, like myself, prefer to reference the
`turn.conf` file when deploying the TURN server with Docker, rather than
the `Readme.turnserver`. Additionally, I think it's important to
synchronize the Prometheus settings from the README into the` turn.conf`
file for better clarity. This way, users won't overlook any essential
options.

Co-authored-by: Ben Chang <ben_chang@htc.com>
2024-11-17 19:49:10 -08:00
Pavel Punsky
4c2a2d568f
Install openssl-1.1.1 on amazonlinux:2 instead of openssl-1.0.1 (#1595)
In preparation to deprecation of openssl below version 1.1.1 switch to
using openssl-1.1.1 on amazonlinux:2 (where 1.0.2 is the default)

Fixes build issue for #1397
2024-11-14 16:59:31 -08:00
tyranron
f8c5695827
Update Debian "bookworm" to 20241111 snapshot in Docker image 2024-11-13 12:17:07 +01:00
Scott Godin
edcdfc8b02
Add new Drain feature (#1529)
Add new Drain feature

-when coturn server is in drain mode
  -current allocations will continue to work as usual
  -new allocations will be rejected with a 403 (Forbidden) response
  -when all allocations go away, then coturn will shutdown
-Enable drain mode with either
  -signaling SIGUSR1
  -turn_admin_server "drain" CLI command

This contribution is from Wire. https://wire.com/
2024-10-27 18:56:58 -07:00
tyranron
8e3a03d2da
Update Debian "bookworm" to 20241016 snapshot in Docker image 2024-10-21 10:47:11 +02:00
Michael Jones
af4c44a818
Additional refactoring of ns_turn_allocation.* to address security scanner concerns (#1514)
You can see the list here:
https://github.com/coturn/coturn/security/code-scanning

In this case, i'm attempting to address:

ns_turn_allocation.c:725 -- Dereferencing NULL pointer. 'ub->bufs'
contains the same NULL value as 'realloc()' did.
ns_turn_allocation.c:724 -- 'realloc' might return null pointer:
assigning null pointer to 'ub->bufs', which is passed as an argument to
'realloc', will cause the original memory block to be leaked.
ns_turn_allocation.c:604 -- Dereferencing NULL pointer. 'a->tcs.elems'
contains the same NULL value as 'realloc()' did.
    ns_turn_allocation.c:582 -- Dereferencing NULL pointer 'tc'.
ns_turn_allocation.c:603 -- 'realloc' might return null pointer:
assigning null pointer to 'a->tcs.elems', which is passed as an argument
to 'realloc', will cause the original memory block to be leaked.
    ns_turn_allocation.c:525 -- Using uninitialized memory '*chi'.
    ns_turn_allocation.c:229 -- Using uninitialized memory '*slot'.

---------

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-10-18 20:54:47 -07:00
redraincatching
08480ce137
fixed linting error in mainrelay.c (#1558)
fixed a formatting problem causing issues with `clang-format` in the
linting action
see
[here](https://github.com/redraincatching/coturn/actions/runs/10262259860)
for an example
2024-10-04 10:29:22 -07:00
eakraly
86a8f659fb
Fix rpm version scripts (#1556)
Fix #1521
2024-10-04 10:28:11 -07:00
Sven Tennie
cbb04aa9a2
Delete dead code (#1563)
`stun_port` isn't read after setting it. Thus, we can remove it.
2024-10-04 10:27:31 -07:00
Mészáros Mihály
e78d8f4fae
Fix cli auth (#1578)
Fix to avoid accept all password except the right cli_password

Co-authored-by: Mészáros Mihály <misi@eper.majd.eu>
2024-10-04 10:26:17 -07:00
tyranron
775d8fbf70
Update Debian "bookworm" to 20240926 snapshot in Docker image 2024-09-30 16:17:57 +03:00
tyranron
bc39021cd7
Update Alpine to 3.20.3 version in Docker image to fix CVE-2024-6119
Some checks failed
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Ubuntu / builds (ubuntu:16.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:18.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:20.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:22.04) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-09-09 12:35:02 +03:00
tyranron
24346a4542
Update Debian "bookworm" to 20240904 snapshot in Docker image 2024-09-06 15:23:11 +03:00
Michael Jones
b523616b1f
Use bool, instead of int, for the functions in ns_turn_msg.c (#1553)
And address knockon effects in other files, e.g. adjust if-statements
and other function parameters and return types.
2024-08-23 17:49:14 -07:00
Pavel Punsky
858b088a88
Reformat code (#1557)
Reformat to address linter error
2024-08-21 15:42:18 -07:00
tyranron
8976c989c8
Update Debian "bookworm" to 20240812 snapshot in Docker image 2024-08-19 13:58:56 +03:00
Sergey Radionov
7711c43525
configure: data files shouldn't be executable (#1542)
for example it creates `/etc/turnserver.conf.default` as executable,
which is strange...
2024-08-05 22:04:27 -07:00
Michael Jones
eee52ad1b9
Update libtelnet (#1545)
to commit
5f5ecee776

Which is the lastest commit in the "develop" branch. 

This seems to fix a couple of places where non-0 is mistakenly returned
as "success" -- why projects don't use bool for these return types is
beyond my understanding.
2024-08-04 17:33:33 -07:00
Michael Jones
958f70d5c2
Use calloc where appropriate, avoid memset when normal buffer initialization works (#1550)
Depends on https://github.com/coturn/coturn/pull/1547
2024-08-04 17:30:58 -07:00
Michael Jones
c4da2a8ea4
Fix make lint (#1547) 2024-08-04 17:21:34 -07:00
Michael Jones
5fa67a65f5
Fix compiler warnings from continuous integration (#1555)
Almost all of the warnings were about truncating pointers, because
sizeof(void*) != sizeof(long) on all platforms.
2024-08-04 15:44:15 -07:00
Michael Jones
ba0ea42914
Fix nodejs/glibc problem with old container images. (#1548)
This problem is caused by this issue:
https://github.com/actions/checkout/issues/1809

Several comments include documentation on various environment variables
to force it to use the older nodejs release still, but probably those
various workarounds will stop working eventually.
2024-08-04 15:40:17 -07:00
David Smitmanis
1f74024a30
windows: Only attempt to bind when the network interface is up (#1527)
Previously if the system had an interface with a static IP configured,
coturn would attempt to bind to that address, even if the interface was
down. This would fail, and prevent coturn from starting (even if there
were other usable interfaces)
2024-07-26 22:22:25 -07:00
tyranron
00ce90cee0
Update Alpine to 3.20.2 version to fix CVE-2024-5535 in Docker image
Some checks failed
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Ubuntu / builds (ubuntu:16.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:18.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:20.04) (push) Has been cancelled
Ubuntu / builds (ubuntu:22.04) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-07-26 13:10:14 +03:00
tyranron
7afa4e9ac9
Update Debian "bookworm" to 20240722 snapshot in Docker image 2024-07-26 12:39:52 +03:00
Pavel Punsky
c7d431a36a
Memset user_db before reading conf file, not after (#1537)
Fixes #1533 and #1534

Memsetting `turn_params.default_users_db` before reading conf file, not
after.
Because auth is read in first iteration so secret was wiped out.

# test plan
Add new test script that uses config file to setup turnserver instead of
cli arguments and confirm it works (fails without the change)
2024-07-14 16:59:26 -07:00
tyranron
d541f56613
Update Debian "bookworm" to 20240701 snapshot in Docker image 2024-07-03 11:50:59 +03:00
tyranron
fbe07c4a16
Update Alpine to 3.20.1 version to fix CVE-2024-4741, CVE-2023-42364 and CVE-2023-42365 in Docker image
Some checks failed
mingw / build (OFF, Release, windows-latest) (push) Has been cancelled
msvc-analyzer / msvc-analyzer (OFF, Release, x64, v143) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v142, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-06-21 07:19:38 +02:00
redraincatching
295b9cfe1a
added support for amazon linux and renamed tests.yml (#1401)
superseding changes made in pr
https://github.com/coturn/coturn/pull/1394 on request of @jonesmz

dependent on pr https://github.com/coturn/coturn/pull/1399 - uses the
composite action for dependency installation i wrote there

added YAML file for amazon linux and renames tests.yml to
ubuntu_tests.yml for clarity
2024-06-16 18:18:50 -07:00
tyranron
0868999b5c
Update Debian "bookworm" to 20240612 snapshot in Docker image 2024-06-13 14:07:26 +02:00
Michael Jones
c3d235b6e9
Check the result of malloc in send_message_to_redis (#1515) 2024-06-02 16:36:27 -07:00
Michael Jones
0de3bda383
Check the result of malloc in mongo_set_realm_option_one (#1516) 2024-06-02 16:35:37 -07:00
Michael Jones
a394fb1cee
Simplify workflow for codeql (#1517) 2024-06-02 16:34:29 -07:00
Michael Jones
868f15a672
Move the hiredis_libevent2 code from common to relay (#1509)
The point of this change is to make the build instructions a bit more
straight forward. Since the hiresevent2 source files are only ever used
by the relay target, this scoping makes sense in general.
2024-06-01 18:16:39 -07:00
Michael Jones
d1db5e590d
Include what you use (#1512)
Use the include-what-you-use program to (partially) clean up header
includes, so that only includes which are needed, and no includes that
are not needed (or at least closer to that ideal) are done.

For a c-language project, the build-time improvements from this change
is minimal. This would have a much bigger impact on a C++ project than a
C-project for build times.

So for coturn, this change is mostly intended to just provide
consistency and make it easier to locate weird issues like strange
dependencies, and unnecessary connections between code.
2024-06-01 18:13:08 -07:00
Michael Jones
ebf7587aaf
Remove deprecated macos-11, add macos-13 and macos-14 (#1511) 2024-06-01 18:10:55 -07:00
Michael Jones
e45d846331
Check the result of malloc in string_list_add (#1495) 2024-05-29 20:49:54 -07:00
Michael Jones
35a3293531
Check the result of realloc and calloc in ch_map_get (#1497) 2024-05-29 20:48:46 -07:00
Michael Jones
66a85ef09e
Address clang-tidy warnings in db files (#1405)
The general approach here was:

- Always declare variables as close to where they are defined as
possible.
- Check for pre-conditions of functions before doing work (e.g. ensure
we can connect to the DB before doing a bunch of string formatting)
- Keep the scope of mutexes as reasonably small as practical.
- Use idiomatic C11, such as for-loops over the thing being iterated,
not while() loops over constants, or variables that aren't modified.
- Prefer if(fail){return} function-body after over `if(not fail){
function-body inside if} return;

Clang-tidy returns a clean bill of health, but while going through this
file i noticed a lot of things that raise questions.

Lack of checking column counts. Lack of handling the possibility of
multiple return values. Questionably handling of strings. Complete lack
of checking function inputs for invalid values (e.g. nullptr).

I'm not going to fix those, my organization doesn't USE the DB drivers,
so i have little interest in re-working the logic beyond addressing
clang-tidy warnings for my own sanity, but i did add TODO comments for
someone else to look at in the future.



Additional note: While the changes look very invasive.... they aren't.

I don't think there is a way to get github to ignore whitespace in the
filediff, but if someone were to compare the commit locally, they'll see
that almost all of the changes are just adjusting indentation.
2024-05-29 20:44:23 -07:00
redraincatching
99777bd585
malloc now allocates space for string terminator (#1507)
addresses a code scanner vulnerability

the combination of `strlen` and `malloc` results in space being
allocated for the string, but not the null terminator required to end
the string, so space for an extra character has to be manually specified

#### references
- CERT C Coding Standard: [MEM35-C. Allocate sufficient memory for an
object](https://www.securecoding.cert.org/confluence/display/c/MEM35-C.+Allocate+sufficient+memory+for+an+object).
- Common Weakness Enumeration:
[CWE-131](https://cwe.mitre.org/data/definitions/131.html).
- Common Weakness Enumeration:
[CWE-120](https://cwe.mitre.org/data/definitions/120.html).
- Common Weakness Enumeration:
[CWE-122](https://cwe.mitre.org/data/definitions/122.html).
2024-05-29 20:42:31 -07:00
Michael Jones
ad94684b23
Use bool over int for the turnutils_uclient program (#1420)
Converts all of the variables in the uclient program that should be bool
but weren't.

A few other minor adjustments made at the behest of clang-tidy, but this
change does not address all of clang-tidy's complaints.
2024-05-29 20:39:51 -07:00
Michael Jones
58dc071b46
Fix lint complaint about comment (#1506) 2024-05-29 19:07:20 -07:00
Michael Jones
6f82083ea3
Run all of the CI except for Docker builds on any change (#1415)
I'm having trouble testing changes in my own fork because many of the CI
workflows are only set to build on a pull request.

Better to just build on any commit.

I've left the docker builds as they are.
2024-05-27 13:50:43 -07:00
Michael Jones
e8fa2f666a
Avoid read-past-end of string in get_bold_admin_title (#1499) 2024-05-27 13:47:54 -07:00
Michael Jones
544382f313
Fix mingw and MSVC ci build (#1491) 2024-05-27 13:43:40 -07:00
Michael Jones
46caa941d3
Check allocation results in add_static_user_account (#1501) 2024-05-27 12:05:21 -07:00
Pavel Punsky
47fcc99853
Address some build issues introduced by api changes (#1505)
#1502 made APIs consistent with using bool as a return value where true
is success and false is failure
In a few places the change broke code

This PR fixes the breakage
2024-05-27 12:00:23 -07:00
Michael Jones
846f717059
Check the result of calloc in handle_logon_request (#1498) 2024-05-27 11:30:49 -07:00
Michael Jones
a32d1a2704
Avoid writing potentially uninitialized data to aes_128 key file (#1500) 2024-05-27 10:56:12 -07:00
Pavel Punsky
17926fe70b
Use active CPU number instead of total number (#1469)
The code used `get_system_number_of_cpus()` instead of
`get_system_active_number_of_cpus()` to configure number of relay
servers.
That caused incorrect number to be used on virtualized systems. See
#1468
2024-05-26 18:35:15 -07:00
redraincatching
90799f5c60
defined a magic number for stun fingerprinting (#1489)
The value `0x5354554e`, used twice in the `ns_turn_msg.c`, was unclear,
and was changed to a macro that better explained its usage, as defined
in [RFC
5389](https://datatracker.ietf.org/doc/html/rfc5389#section-15.5)
2024-05-26 18:34:10 -07:00
Michael Jones
525550ab86
Always run lint, regardless of branch (#1492)
Someone working on a branch in their own fork won't see the lint running
on their github-actions CI until they open a pull request.

It'd be much easier to ensure changes being worked on are going to pass
the linter if the linter runs before the last step of opening the PR.
2024-05-26 18:27:39 -07:00
Michael Jones
4e8524d9d7
avoid potential nullptr derefernence in udp_create_server_socket (#1496) 2024-05-26 18:22:31 -07:00
Michael Jones
f3b73f60d0
Change the various map functions to return bool instead of inconsistantly return 0, 1, or -1 (#1502) 2024-05-26 17:45:18 -07:00
Michael Jones
6fc5cf31e9
Check the result of malloc in del_alt_server (#1503) 2024-05-26 17:34:15 -07:00
Michael Jones
2c45aa731c
Avoid nullptr dereference of server variable in various functions (#1504) 2024-05-26 17:32:02 -07:00
tyranron
74f279d695
Upgrade Alpine to 3.20 version in Docker image
Some checks failed
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
C/C++ CI / builds (ubuntu:16.04) (push) Has been cancelled
C/C++ CI / builds (ubuntu:18.04) (push) Has been cancelled
C/C++ CI / builds (ubuntu:20.04) (push) Has been cancelled
C/C++ CI / builds (ubuntu:22.04) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-05-24 16:56:31 +02:00
tyranron
d72919e4e1
Update Debian "bookworm" to 20240513 snapshot in Docker image 2024-05-14 15:01:30 +02:00
Gustavo Garcia
14e6d16d14
Fix msvc analyzer error on goto label on rfc5769check (#1486)
rfc5769check.c file is using ERROR as a label for gotos but apparently
that name is already used for a constant and msvc analyzer detects it as
an error.

Rename it to "err" that is already used in other parts of the codebase
and also more consistent in terms of casing.

Co-authored-by: Gustavo Garcia <gustavogb@mail.com>
2024-05-05 12:19:10 +02:00
Stefan Junker
158fe9b698
Fix buffer overflow in generate_enc_password with increase rsalt by 2 (#1463)
before this change i see a bufferflow during `readable_string`.
2024-05-04 18:26:35 +02:00
tyranron
e1d8661b40
Update Debian "bookworm" to 20240423 snapshot in Docker image 2024-04-24 12:19:08 +03:00
Gustavo Garcia
386371c174
Fix lint errors 2024-04-21 23:05:29 +02:00
Nikolayshcx
eb3af26867
Add support for raw public keys (Rfc 7250) (#1458)
Resolving #1456

---------

Co-authored-by: nmegdanov <nikolay.megdanov@softavail.com>
2024-04-19 17:12:48 +02:00
Gustavo Garcia
c2d13700ac Fix clang-format lint warnings 2024-04-19 17:08:49 +02:00
Gustavo Garcia
28294cf053 Fix const during free warning in rfc5769check app 2024-04-19 16:23:30 +02:00
Kang Lin
5b68014699
Refactor: peer_input_handle (#1325) 2024-04-19 12:09:43 +02:00
tyranron
bc54a4d940
Update Debian "bookworm" to 20240408 snapshot in Docker image 2024-04-10 14:30:37 +03:00
redraincatching
e96f22ab71
workflow tidying (#1396)
Normalisation of some of the workflow files
2024-04-09 23:18:03 +02:00
Wittmer, Christian
b009624902
Update turnserver.conf Example about listening-ip (#1336)
Fixes #1294
2024-04-09 23:03:53 +02:00
NO NAME
3f66c028fa
Fix Cmake find issue in libevent (#1466)
Fixed an issue in libevent's CMake configuration where pthreads were not
correctly added to the optional components list, leading to a
compilation error. #1448

Co-authored-by: linwenchen <wenchen0803@qq.com>
2024-04-09 11:51:31 +02:00
Kang Lin
0fc60d48fa
CMake: Declare the variable nearby (#1387)
CMake: Declare the variable nearby
2024-03-31 09:57:54 +02:00
Pavel Punsky
edebb9ad05
Print version only, no extra lines (#1441)
Before
<img width="615" alt="Screenshot 2024-03-02 at 2 47 48 PM"
src="https://github.com/coturn/coturn/assets/2505440/c3f01e97-914c-4391-af32-d3442d265e90">

After
<img width="402" alt="Screenshot 2024-03-02 at 2 47 28 PM"
src="https://github.com/coturn/coturn/assets/2505440/ce3deb7b-5f70-4158-8cd9-eceae0dcc995">
2024-03-31 09:53:21 +02:00
dependabot[bot]
9a79c813e3
Upgrade softprops/action-gh-release GitHub Action from 1 to 2 version (#1449) 2024-03-11 11:40:29 +01:00
ashamedbit
412788b120
Fix memory leak in rfc5769check.c (#1410)
I came across the open issue #1368 which is a leaksanitizer report about
a leak that happens on make check. I was able to reproduce the bug on
running `make check` and was able to generate a patch for it. The leak
happens within function `check_oauth`.

Issue: The variable `base64encoded_ltp` is allocated within
`base64_encode` however it is not de-allocated within the coming loop.

I have verified that after the patch, the leak no longer occurs through
`leaksanitizer` (and there is no double free for that matter)

---------

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-03-03 14:04:40 -08:00
ashamedbit
456e2e81b3
Fix memory leak in netengine.c (#1411)
This is in response to issue #1366
The clang static analyzer basically claims that there is a memory leak
happening in `set_ssl_ctx` for the variable `args`. The leak is
triggered when the base event `base` is NULL and the condition within
`set_ssl_ctx` is not triggered. Therefore as a patch I am adding an else
condition to free it. (It cannot be freed after the event is created by
`event_new` because `args` can be invoked as argument for callback
function later on)

Please let me know if this patch is helpful :)

---------

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-03-02 14:15:58 -08:00
ashamedbit
68b9f19f7f
Fix memory leak on http_server.c (#1412)
This is in response to issue #1365.
The clang static analyzer basically claims that there is a memory leak
happening in `parse_http_request_1` for the variable `kv`. The leak is
triggered when evhttp_parse_query_str fails and is unable to obtain key
value pairs for a given URI. In this case ret is freed, however kv is
still not freed and thereafter not used. Therefore as a patch I am
freeing kv right after ret is freed.

Please let me know if this patch is helpful :)

---------

Co-authored-by: Pavel Punsky <eakraly@users.noreply.github.com>
2024-03-02 14:10:53 -08:00
redraincatching
294a2b69a0
ubuntu build dependencies extracted to composite actions (#1399)
superseding changes made in pr #1394 on request of @jonesmz 

extracted ubuntu build dependencies into a composite action for
maintainability reasons
2024-03-02 13:45:24 -08:00
Pavel Punsky
2c265c9777
Delete unused variable (#1437) 2024-02-25 16:07:08 -08:00
redraincatching
ac00b41a8e
changed variables in stunclient.c to bool (C11) (#1421)
# changed variables that appeared in `stunclient.c` and their uses to
`bool` to follow C11 idioms
## approach was as follows:
- if a variable of type `int` was only being used as a boolean, replace
it with bool as defined in `<stdbool.h>`
- replace its declaration and assignment with true/false, depending on
prior assignment as 0/1

changes were only made when i was certain the variables were not being
used as an int, so i may have missed some

---

## variables changed in `stunclient.c`
- `rfc5780`
- `change_ip`
- `change_port`

their usages were changed only where they appeared in the apps
directory, and then everywhere that generated a warning after make

- `stunclient.c` itself
- `natdiscovery.c`
2024-02-20 18:43:24 -08:00
tyranron
873cabd6a2
Update Debian "bookworm" to 20240211 snapshot in Docker image 2024-02-14 12:54:35 +02:00
redraincatching
0c8d646e2d
added missing function prototype of turn_random_number() (#1428)
trivial - cmake generated a warning that `ns_turn_msg.c` used a function
that had no prior prototype - most other files used the `turn_random()`
function but this uses `turn_random_number()` which has no prototype, so
i've added it to the header file
2024-02-10 20:57:33 -08:00
Jan Brasna
9dfe8d5128
Fix no-tls warning typo (#1426)
Trivial log warning typo introduced in #1256 corrected.
2024-02-09 20:15:19 -08:00
dominiquefournier
460cfa38af
Update SQLite.md (#1429)
Markdown is now proper
2024-02-09 20:14:49 -08:00
tyranron
94ade4b01f
Update Debian "bookworm" to 20240130 snapshot in Docker image 2024-02-01 12:33:57 +02:00
Michael Jones
2459db6266
Adjust wording in cmake message when prometheous cannot be found. (#1418) 2024-01-31 17:57:20 -08:00
tyranron
d274637d51
Update Alpine to 3.19.1 version in Docker image to fix CVE-2023-6129, CVE-2023-6237 and CVE-2024-0727
Some checks failed
mingw / build (OFF, Debug, windows-latest) (push) Has been cancelled
mingw / build (OFF, Release, windows-latest) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (OFF, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Debug, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, Win32, v141, windows-latest, x86-windows) (push) Has been cancelled
msvc / ${{matrix.os}}-vc-${{matrix.VCPKG_PLATFORM_TOOLSET}}-${{matrix.CMAKE_GENERATOR_PLATFORM}}-${{matrix.BUILD_TYPE}}-${{matrix.BUILD_SHARED_LIBS}} (ON, Release, x64, v143, windows-latest, x64-windows) (push) Has been cancelled
Docker CI / test (amd64, alpine) (push) Has been cancelled
Docker CI / test (amd64, debian) (push) Has been cancelled
Docker CI / test (arm32v6, alpine) (push) Has been cancelled
Docker CI / test (arm32v6, debian) (push) Has been cancelled
Docker CI / test (arm32v7, alpine) (push) Has been cancelled
Docker CI / test (arm32v7, debian) (push) Has been cancelled
Docker CI / test (arm64v8, alpine) (push) Has been cancelled
Docker CI / test (arm64v8, debian) (push) Has been cancelled
Docker CI / test (i386, alpine) (push) Has been cancelled
Docker CI / test (i386, debian) (push) Has been cancelled
Docker CI / test (ppc64le, alpine) (push) Has been cancelled
Docker CI / test (ppc64le, debian) (push) Has been cancelled
Docker CI / test (s390x, debian) (push) Has been cancelled
Docker CI / push (alpine, docker.io) (push) Has been cancelled
Docker CI / push (alpine, ghcr.io) (push) Has been cancelled
Docker CI / push (alpine, quay.io) (push) Has been cancelled
Docker CI / push (debian, docker.io) (push) Has been cancelled
Docker CI / push (debian, ghcr.io) (push) Has been cancelled
Docker CI / push (debian, quay.io) (push) Has been cancelled
Docker CI / release (GitHub) (push) Has been cancelled
2024-01-29 12:07:35 +02:00
Michael Jones
da332ed9e7
Add the InsertBraces command for clang-format to ensure that all conditionals always have braces (#1408)
- Why? Because code where conditionals lack braces is much harder to read, and prone to indentation confusion.
- How? Just added an extra flag to .clang-format and re-ran clang-format on all the files.

I also moved .clang-format up to the top level of the repo so that it can be applied to the fuzz targets as well.
2024-01-27 16:38:40 -08:00
111 changed files with 7373 additions and 6073 deletions

View File

@ -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
...

View File

@ -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,
'

View 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/

View File

@ -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
View 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

View File

@ -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/

View File

@ -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

View File

@ -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

View File

@ -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: |

View File

@ -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
View 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') }}

View File

@ -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/

View File

@ -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' }}

View File

@ -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 }}

View File

@ -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' }}

View File

@ -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

View File

@ -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>

View File

@ -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
View File

@ -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:

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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
View File

@ -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}

View File

@ -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>

View File

@ -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)

View File

@ -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]

View File

@ -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/ \

View File

@ -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/ \

View File

@ -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.

View File

@ -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`

View File

@ -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.
#

View File

@ -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
View 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
View 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"

View File

@ -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`

View File

@ -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;
}

View File

@ -2,7 +2,7 @@
# Common settings script.
TURNVERSION=4.5.2
TURNVERSION=4.6.3
BUILDDIR=~/rpmbuild
ARCH=`uname -p`

View File

@ -1,5 +1,5 @@
Name: turnserver
Version: 4.6.2
Version: 4.6.3
Release: 0%{dist}
Summary: Coturn TURN Server

View 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 "----------------------------------------------------"
####

View File

@ -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})

View File

@ -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;
}
@ -539,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
@ -559,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
@ -590,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
@ -610,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);
@ -644,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
@ -668,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;
}
@ -686,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
;
}
@ -697,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;
}
@ -762,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;
}
@ -810,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;
@ -858,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;
@ -889,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;
@ -909,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;
@ -929,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 {
@ -943,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 //////////////////////
@ -1047,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);
}
@ -1065,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);
@ -1091,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]) {
@ -1153,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);
}
}
}
@ -1274,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;
@ -1304,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;
@ -1314,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;
@ -1351,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;

View File

@ -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;
@ -242,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);

View File

@ -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__

View File

@ -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;

View File

@ -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

View File

@ -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); }
///////////////////////////////////////////////////////

View File

@ -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);
///////////////////////////////////////////////////////////////

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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 *));

View File

@ -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);
}
}
//////////////////////////////////////////////////////////////////

View File

@ -37,6 +37,8 @@
#include <event2/event.h>
#include <stddef.h> // for size_t
#ifdef __cplusplus
extern "C" {
#endif

View File

@ -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()

View File

@ -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';

View File

@ -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);

View File

@ -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;

View File

@ -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;
}

View File

@ -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) {

View File

@ -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

View File

@ -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);

View File

@ -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);

View File

@ -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);
@ -796,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;
@ -812,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;
@ -863,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;
@ -882,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;
}
@ -893,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);
@ -929,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 */
@ -958,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));
}
}
//////////////////////////////////////////////////////////////////

View File

@ -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;
}
}
}

View File

@ -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, ...);

View File

@ -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;

View File

@ -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);

View File

@ -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

View File

@ -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);

View File

@ -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
@ -236,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]));
}
@ -299,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;
}
@ -324,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);
@ -346,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);
}
}
}
@ -459,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);
@ -504,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;
}
@ -711,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 {
@ -750,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 {
@ -974,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);
@ -1046,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
@ -1092,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) {
@ -1194,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))) {
@ -1238,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;
}
}
}
}
@ -1251,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 */
@ -1314,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))) {
@ -1346,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;
}
}
}
}
@ -1403,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))) {
@ -1427,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;
}
}
}
}
@ -1473,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]) {
@ -1549,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;
@ -1579,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();
@ -1622,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,
@ -1804,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)
@ -1822,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);
@ -1871,4 +1903,18 @@ void setup_server(void) {
void init_listener(void) { memset(&turn_params.listener, 0, sizeof(struct listener_server)); }
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.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.is_draining = true;
}
}
turn_params.drain_turn_server = true;
}
///////////////////////////////

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -35,6 +35,42 @@ prom_counter_t *turn_total_traffic_peer_sentb;
prom_gauge_t *turn_total_allocations;
#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) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "prometheus collector disabled, not started\n");
@ -103,13 +139,8 @@ void start_prometheus_server(void) {
turn_total_allocations = prom_collector_registry_must_register_metric(
prom_gauge_new("turn_total_allocations", "Represents current allocations number", 1, typeLabel));
promhttp_set_active_collector_registry(NULL);
// 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
@ -127,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;

View File

@ -18,7 +18,6 @@ extern "C" {
#endif
#include <microhttpd.h>
#include <prom.h>
#include <promhttp.h>
#ifdef __cplusplus
}
#endif /* __clplusplus */

View File

@ -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

View File

@ -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);
}
//////////////////////////////////////////////////

View File

@ -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);

View File

@ -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;

View File

@ -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), &ltp_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;

View File

@ -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);

View File

@ -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
)
)

View File

@ -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++;
}

View File

@ -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

View File

@ -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);

View File

@ -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;
}

View File

@ -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);

View File

@ -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) {

View File

@ -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

View File

@ -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);
///////////////////////////////////////////////////////////////

View File

@ -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];

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -30,6 +30,11 @@
#include "ns_turn_allocation.h"
#include "ns_turn_ioalib.h"
#include "ns_turn_msg_defs.h" // for STUN_VALID_CHANNEL
#include "ns_turn_utils.h" // for TURN_LOG_FUNC, TURN_LOG_LEVEL_ERROR
#include <stdlib.h> // for NULL, size_t, free, realloc, calloc
#include <string.h> // for memset, memcpy
/////////////// Permission forward declarations /////////////////
@ -49,88 +54,89 @@ void init_allocation(void *owner, allocation *a, ur_map *tcp_connections) {
}
void clear_allocation(allocation *a, SOCKET_TYPE socket_type) {
if (a) {
if (a->is_valid)
turn_report_allocation_delete(a, socket_type);
if (a->tcs.elems) {
size_t i;
size_t sz = a->tcs.sz;
for (i = 0; i < sz; ++i) {
tcp_connection *tc = a->tcs.elems[i];
if (tc) {
delete_tcp_connection(tc);
a->tcs.elems[i] = NULL;
}
}
free(a->tcs.elems);
a->tcs.elems = NULL;
}
a->tcs.sz = 0;
{
int i;
for (i = 0; i < ALLOC_PROTOCOLS_NUMBER; ++i) {
clear_ioa_socket_session_if(a->relay_sessions[i].s, a->owner);
clear_relay_endpoint_session_data(&(a->relay_sessions[i]));
IOA_EVENT_DEL(a->relay_sessions[i].lifetime_ev);
}
}
/* The order is important here: */
free_turn_permission_hashtable(&(a->addr_to_perm));
ch_map_clean(&(a->chns));
a->is_valid = 0;
if (!a) {
return;
}
if (a->is_valid) {
turn_report_allocation_delete(a, socket_type);
}
if (a->tcs.elems) {
for (size_t i = 0; i < a->tcs.sz; ++i) {
tcp_connection *tc = a->tcs.elems[i];
if (tc) {
delete_tcp_connection(tc);
a->tcs.elems[i] = NULL;
}
}
free(a->tcs.elems);
a->tcs.elems = NULL;
}
a->tcs.sz = 0;
for (size_t i = 0; i < ALLOC_PROTOCOLS_NUMBER; ++i) {
clear_ioa_socket_session_if(a->relay_sessions[i].s, a->owner);
clear_relay_endpoint_session_data(&(a->relay_sessions[i]));
IOA_EVENT_DEL(a->relay_sessions[i].lifetime_ev);
}
/* The order is important here: */
free_turn_permission_hashtable(&(a->addr_to_perm));
ch_map_clean(&(a->chns));
a->is_valid = 0;
}
relay_endpoint_session *get_relay_session(allocation *a, int family) {
if (a)
if (a) {
return &(a->relay_sessions[ALLOC_INDEX(family)]);
}
return NULL;
}
int get_relay_session_failure(allocation *a, int family) {
if (a)
if (a) {
return a->relay_sessions_failure[ALLOC_INDEX(family)];
}
return 0;
}
void set_relay_session_failure(allocation *a, int family) {
if (a)
if (a) {
a->relay_sessions_failure[ALLOC_INDEX(family)] = 1;
}
}
ioa_socket_handle get_relay_socket(allocation *a, int family) {
if (a)
if (a) {
return a->relay_sessions[ALLOC_INDEX(family)].s;
}
return NULL;
}
void set_allocation_family_invalid(allocation *a, int family) {
if (a) {
size_t index = ALLOC_INDEX(family);
if (a->relay_sessions[index].s) {
if (a->tcs.elems) {
size_t i;
size_t sz = a->tcs.sz;
for (i = 0; i < sz; ++i) {
tcp_connection *tc = a->tcs.elems[i];
if (tc) {
if (tc->peer_s && (get_ioa_socket_address_family(tc->peer_s) == family)) {
delete_tcp_connection(tc);
a->tcs.elems[i] = NULL;
}
if (!a) {
return;
}
const size_t index = ALLOC_INDEX(family);
if (a->relay_sessions[index].s) {
if (a->tcs.elems) {
for (size_t i = 0; i < a->tcs.sz; ++i) {
tcp_connection *tc = a->tcs.elems[i];
if (tc) {
if (tc->peer_s && (get_ioa_socket_address_family(tc->peer_s) == family)) {
delete_tcp_connection(tc);
a->tcs.elems[i] = NULL;
}
}
}
clear_ioa_socket_session_if(a->relay_sessions[index].s, a->owner);
clear_relay_endpoint_session_data(&(a->relay_sessions[index]));
IOA_EVENT_DEL(a->relay_sessions[index].lifetime_ev);
}
clear_ioa_socket_session_if(a->relay_sessions[index].s, a->owner);
clear_relay_endpoint_session_data(&(a->relay_sessions[index]));
IOA_EVENT_DEL(a->relay_sessions[index].lifetime_ev);
}
}
@ -142,16 +148,17 @@ void set_allocation_lifetime_ev(allocation *a, turn_time_t exp_time, ioa_timer_h
}
}
int is_allocation_valid(const allocation *a) {
if (a)
bool is_allocation_valid(const allocation *a) {
if (a) {
return a->is_valid;
else
return 0;
}
return false;
}
void set_allocation_valid(allocation *a, int value) {
if (a)
void set_allocation_valid(allocation *a, bool value) {
if (a) {
a->is_valid = value;
}
}
turn_permission_info *allocation_get_permission(allocation *a, const ioa_addr *addr) {
@ -163,92 +170,86 @@ turn_permission_info *allocation_get_permission(allocation *a, const ioa_addr *a
///////////////////////////// TURN_PERMISSION /////////////////////////////////
static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value);
static bool delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value);
void turn_permission_clean(turn_permission_info *tinfo) {
if (tinfo && tinfo->allocated) {
if (tinfo->verbose) {
char s[257] = "\0";
addr_to_string(&(tinfo->addr), (uint8_t *)s);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s deleted\n", tinfo->session_id, s);
}
if (!(tinfo->lifetime_ev)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n", __FUNCTION__);
}
IOA_EVENT_DEL(tinfo->lifetime_ev);
lm_map_foreach(&(tinfo->chns), (foreachcb_type)delete_channel_info_from_allocation_map);
lm_map_clean(&(tinfo->chns));
memset(tinfo, 0, sizeof(turn_permission_info));
if (!tinfo || !tinfo->allocated) {
return;
}
if (tinfo->verbose) {
char s[257] = "\0";
addr_to_string(&(tinfo->addr), (uint8_t *)s);
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "session %018llu: peer %s deleted\n", tinfo->session_id, s);
}
if (!(tinfo->lifetime_ev)) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) permission to be cleaned\n", __FUNCTION__);
}
IOA_EVENT_DEL(tinfo->lifetime_ev);
lm_map_foreach(&(tinfo->chns), (foreachcb_type)delete_channel_info_from_allocation_map);
lm_map_clean(&(tinfo->chns));
memset(tinfo, 0, sizeof(turn_permission_info));
}
static void init_turn_permission_hashtable(turn_permission_hashtable *map) {
if (map)
if (map) {
memset(map, 0, sizeof(turn_permission_hashtable));
}
}
static void free_turn_permission_hashtable(turn_permission_hashtable *map) {
if (map) {
if (!map) {
return;
}
size_t i;
for (i = 0; i < TURN_PERMISSION_HASHTABLE_SIZE; ++i) {
for (size_t i = 0; i < TURN_PERMISSION_HASHTABLE_SIZE; ++i) {
turn_permission_array *parray = &(map->table[i]);
turn_permission_array *parray = &(map->table[i]);
{
size_t j;
for (j = 0; j < TURN_PERMISSION_ARRAY_SIZE; ++j) {
turn_permission_slot *slot = &(parray->main_slots[j]);
for (size_t j = 0; j < TURN_PERMISSION_ARRAY_SIZE; ++j) {
turn_permission_slot *slot = &(parray->main_slots[j]);
if (slot->info.allocated) {
turn_permission_clean(&(slot->info));
}
}
if (parray->extra_slots) {
for (size_t j = 0; j < parray->extra_sz; ++j) {
turn_permission_slot *slot = parray->extra_slots[j];
if (slot) {
if (slot->info.allocated) {
turn_permission_clean(&(slot->info));
}
free(slot);
parray->extra_slots[j] = NULL;
}
}
if (parray->extra_slots) {
size_t j;
for (j = 0; j < parray->extra_sz; ++j) {
turn_permission_slot *slot = parray->extra_slots[j];
if (slot) {
if (slot->info.allocated) {
turn_permission_clean(&(slot->info));
}
free(slot);
}
}
free(parray->extra_slots);
parray->extra_slots = NULL;
}
parray->extra_sz = 0;
free(parray->extra_slots);
parray->extra_slots = NULL;
}
parray->extra_sz = 0;
}
}
static turn_permission_info *get_from_turn_permission_hashtable(turn_permission_hashtable *map, const ioa_addr *addr) {
if (!addr || !map)
if (!addr || !map) {
return NULL;
}
uint32_t index = addr_hash_no_port(addr) & (TURN_PERMISSION_HASHTABLE_SIZE - 1);
turn_permission_array *parray = &(map->table[index]);
{
size_t i;
for (i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) {
turn_permission_slot *slot = &(parray->main_slots[i]);
if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) {
return &(slot->info);
}
for (size_t i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) {
turn_permission_slot *slot = &(parray->main_slots[i]);
if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) {
return &(slot->info);
}
}
if (parray->extra_slots) {
size_t i;
size_t sz = parray->extra_sz;
for (i = 0; i < sz; ++i) {
for (size_t i = 0; i < parray->extra_sz; ++i) {
turn_permission_slot *slot = parray->extra_slots[i];
if (slot->info.allocated && addr_eq_no_port(&(slot->info.addr), addr)) {
return &(slot->info);
@ -270,7 +271,7 @@ static void ch_info_clean(ch_info *c) {
}
}
static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value) {
static bool delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_value_type value) {
UNUSED_ARG(key);
if (value) {
@ -283,41 +284,52 @@ static int delete_channel_info_from_allocation_map(ur_map_key_type key, ur_map_v
ch_info_clean(chn);
}
return 0;
return false;
}
void turn_channel_delete(ch_info *chn) {
if (chn) {
int port = addr_get_port(&(chn->peer_addr));
if (port < 1) {
char s[129];
addr_to_string(&(chn->peer_addr), (uint8_t *)s);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) channel to be cleaned: port is empty: %s\n",
__FUNCTION__, s);
}
{
turn_permission_info *tinfo = (turn_permission_info *)chn->owner;
if (tinfo) {
lm_map_del(&(tinfo->chns), (ur_map_key_type)port, NULL);
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) channel to be cleaned: permission is empty\n",
__FUNCTION__);
}
}
delete_channel_info_from_allocation_map((ur_map_key_type)port, (ur_map_value_type)chn);
if (!chn) {
return;
}
int port = addr_get_port(&(chn->peer_addr));
if (port < 1) {
char s[129];
addr_to_string(&(chn->peer_addr), (uint8_t *)s);
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (1) channel to be cleaned: port is empty: %s\n", __FUNCTION__,
s);
}
turn_permission_info *tinfo = (turn_permission_info *)chn->owner;
if (tinfo) {
lm_map_del(&(tinfo->chns), (ur_map_key_type)port, NULL);
} else {
TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "!!! %s: strange (2) channel to be cleaned: permission is empty\n",
__FUNCTION__);
}
delete_channel_info_from_allocation_map((ur_map_key_type)port, (ur_map_value_type)chn);
}
ch_info *allocation_get_new_ch_info(allocation *a, uint16_t chnum, ioa_addr *peer_addr) {
if (!a) {
return NULL;
}
turn_permission_info *tinfo = get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr);
if (!tinfo)
if (!tinfo) {
tinfo = allocation_add_permission(a, peer_addr);
if (!tinfo) {
return NULL;
}
}
ch_info *chn = ch_map_get(&(a->chns), chnum, 1);
if (!chn) {
return NULL;
}
chn->allocated = 1;
chn->allocated = true;
chn->chnum = chnum;
chn->port = addr_get_port(peer_addr);
addr_cpy(&(chn->peer_addr), peer_addr);
@ -369,20 +381,34 @@ ch_info *get_turn_channel(turn_permission_info *tinfo, ioa_addr *addr) {
turn_permission_hashtable *allocation_get_turn_permission_hashtable(allocation *a) { return &(a->addr_to_perm); }
turn_permission_info *allocation_add_permission(allocation *a, const ioa_addr *addr) {
if (a && addr) {
if (!a || !addr) {
return NULL;
}
turn_permission_hashtable *map = &(a->addr_to_perm);
uint32_t hash = addr_hash_no_port(addr);
size_t fds = (size_t)(hash & (TURN_PERMISSION_HASHTABLE_SIZE - 1));
turn_permission_hashtable *map = &(a->addr_to_perm);
uint32_t hash = addr_hash_no_port(addr);
size_t fds = (size_t)(hash & (TURN_PERMISSION_HASHTABLE_SIZE - 1));
turn_permission_array *parray = &(map->table[fds]);
turn_permission_array *parray = &(map->table[fds]);
turn_permission_slot *slot = NULL;
turn_permission_slot *slot = NULL;
{
size_t i;
for (i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) {
slot = &(parray->main_slots[i]);
for (size_t i = 0; i < TURN_PERMISSION_ARRAY_SIZE; ++i) {
slot = &(parray->main_slots[i]);
if (!(slot->info.allocated)) {
break;
} else {
slot = NULL;
}
}
if (!slot) {
size_t old_sz = parray->extra_sz;
turn_permission_slot **slots = parray->extra_slots;
if (slots) {
for (size_t i = 0; i < old_sz; ++i) {
slot = slots[i];
if (!(slot->info.allocated)) {
break;
} else {
@ -392,160 +418,151 @@ turn_permission_info *allocation_add_permission(allocation *a, const ioa_addr *a
}
if (!slot) {
size_t old_sz = parray->extra_sz;
turn_permission_slot **slots = parray->extra_slots;
if (slots) {
size_t i;
for (i = 0; i < old_sz; ++i) {
slot = slots[i];
if (!(slot->info.allocated)) {
break;
} else {
slot = NULL;
}
}
size_t old_sz_mem = old_sz * sizeof(turn_permission_slot *);
turn_permission_slot **new_slots =
(turn_permission_slot **)realloc(parray->extra_slots, old_sz_mem + sizeof(turn_permission_slot *));
if (!new_slots) {
return NULL;
}
parray->extra_slots = new_slots;
slots = parray->extra_slots;
parray->extra_sz = old_sz + 1;
slot = (turn_permission_slot *)malloc(sizeof(turn_permission_slot));
if (!slot) {
size_t old_sz_mem = old_sz * sizeof(turn_permission_slot *);
parray->extra_slots =
(turn_permission_slot **)realloc(parray->extra_slots, old_sz_mem + sizeof(turn_permission_slot *));
slots = parray->extra_slots;
parray->extra_sz = old_sz + 1;
slots[old_sz] = (turn_permission_slot *)malloc(sizeof(turn_permission_slot));
slot = slots[old_sz];
return NULL;
}
slots[old_sz] = slot;
}
memset(slot, 0, sizeof(turn_permission_slot));
slot->info.allocated = 1;
turn_permission_info *elem = &(slot->info);
addr_cpy(&(elem->addr), addr);
elem->owner = a;
return elem;
} else {
return NULL;
}
memset(slot, 0, sizeof(turn_permission_slot));
slot->info.allocated = true;
turn_permission_info *elem = &(slot->info);
addr_cpy(&(elem->addr), addr);
elem->owner = a;
return elem;
}
ch_info *ch_map_get(ch_map *map, uint16_t chnum, int new_chn) {
ch_info *ret = NULL;
if (map) {
size_t index = (size_t)(chnum & (CH_MAP_HASH_SIZE - 1));
ch_map_array *a = &(map->table[index]);
ch_info *ch_map_get(ch_map *const map, const uint16_t chnum, const int new_chn) {
if (!map) {
return NULL;
}
size_t i;
for (i = 0; i < CH_MAP_ARRAY_SIZE; ++i) {
ch_info *chi = &(a->main_chns[i]);
if (chi->allocated) {
if (!new_chn && (chi->chnum == chnum)) {
return chi;
}
} else if (new_chn) {
const size_t index = (size_t)(chnum & (CH_MAP_HASH_SIZE - 1));
ch_map_array *const a = &(map->table[index]);
for (size_t i = 0; i < CH_MAP_ARRAY_SIZE; ++i) {
ch_info *const chi = &(a->main_chns[i]);
if (chi->allocated) {
if (!new_chn && (chi->chnum == chnum)) {
return chi;
}
}
size_t old_sz = a->extra_sz;
if (old_sz && a->extra_chns) {
for (i = 0; i < old_sz; ++i) {
ch_info *chi = a->extra_chns[i];
if (chi) {
if (chi->allocated) {
if (!new_chn && (chi->chnum == chnum)) {
return chi;
}
} else if (new_chn) {
return chi;
}
}
}
}
if (new_chn) {
size_t old_sz_mem = old_sz * sizeof(ch_info *);
a->extra_chns = (ch_info **)realloc(a->extra_chns, old_sz_mem + sizeof(ch_info *));
a->extra_chns[old_sz] = (ch_info *)calloc(sizeof(ch_info), 1);
a->extra_sz += 1;
return a->extra_chns[old_sz];
} else if (new_chn) {
return chi;
}
}
return ret;
const size_t old_sz = a->extra_sz;
if (old_sz && a->extra_chns) {
for (size_t i = 0; i < old_sz; ++i) {
ch_info *const chi = a->extra_chns[i];
if (chi) {
if (chi->allocated) {
if (!new_chn && (chi->chnum == chnum)) {
return chi;
}
} else if (new_chn) {
return chi;
}
}
}
}
if (new_chn) {
const size_t old_sz_mem = old_sz * sizeof(ch_info *);
ch_info **const pTmp = (ch_info **)realloc(a->extra_chns, old_sz_mem + sizeof(ch_info *));
if (!pTmp) {
return NULL;
}
a->extra_chns = pTmp;
a->extra_chns[old_sz] = (ch_info *)calloc(1, sizeof(ch_info));
if (!a->extra_chns[old_sz]) {
// if the realloc succeeds, but the calloc fails, we don't attempt to shrink the realloc back down
// by not recording the change to the size, we allow the next call to this function to realloc the
// block to presumably the same size it already is, which should be fine and not result in any leaks.
return NULL;
}
a->extra_sz += 1;
return a->extra_chns[old_sz];
}
return NULL;
}
void ch_map_clean(ch_map *map) {
if (map) {
size_t index;
for (index = 0; index < CH_MAP_HASH_SIZE; ++index) {
if (!map) {
return;
}
ch_map_array *a = &(map->table[index]);
for (size_t index = 0; index < CH_MAP_HASH_SIZE; ++index) {
ch_map_array *a = &(map->table[index]);
size_t i;
for (i = 0; i < CH_MAP_ARRAY_SIZE; ++i) {
ch_info *chi = &(a->main_chns[i]);
if (chi->allocated) {
ch_info_clean(chi);
}
for (size_t i = 0; i < CH_MAP_ARRAY_SIZE; ++i) {
ch_info *chi = &(a->main_chns[i]);
if (chi->allocated) {
ch_info_clean(chi);
}
if (a->extra_chns) {
size_t sz = a->extra_sz;
for (i = 0; i < sz; ++i) {
ch_info *chi = a->extra_chns[i];
if (chi) {
if (chi->allocated) {
ch_info_clean(chi);
}
free(chi);
a->extra_chns[i] = NULL;
}
}
free(a->extra_chns);
a->extra_chns = NULL;
}
a->extra_sz = 0;
}
if (a->extra_chns) {
for (size_t i = 0; i < a->extra_sz; ++i) {
ch_info *chi = a->extra_chns[i];
if (chi) {
if (chi->allocated) {
ch_info_clean(chi);
}
free(chi);
a->extra_chns[i] = NULL;
}
}
free(a->extra_chns);
a->extra_chns = NULL;
}
a->extra_sz = 0;
}
}
////////////////// TCP connections ///////////////////////////////
static void set_new_tc_id(uint8_t server_id, tcp_connection *tc) {
allocation *a = (allocation *)(tc->owner);
ur_map *map = a->tcp_connections;
uint32_t newid;
uint32_t sid = server_id;
sid = sid << 24;
const uint32_t sid = ((uint32_t)server_id) << 24;
allocation *const a = (allocation *)(tc->owner);
if (!a || !a->tcp_connections) {
return;
}
uint32_t newid = 0;
do {
newid = 0;
while (!newid) {
newid = (uint32_t)turn_random();
if (!newid) {
continue;
}
newid = newid & 0x00FFFFFF;
if (!newid) {
continue;
}
newid = newid | sid;
}
} while (ur_map_get(map, (ur_map_key_type)newid, NULL));
do {
newid = ((uint32_t)turn_random()) & 0x00FFFFFF;
} while (!newid);
newid = newid | sid;
} while (ur_map_get(a->tcp_connections, (ur_map_key_type)newid, NULL));
tc->id = newid;
ur_map_put(map, (ur_map_key_type)newid, (ur_map_value_type)tc);
ur_map_put(a->tcp_connections, (ur_map_key_type)newid, (ur_map_value_type)tc);
}
tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid *tid, ioa_addr *peer_addr,
int *err_code) {
tcp_connection_list *tcl = &(a->tcs);
if (!tcl) {
return NULL;
}
if (tcl->elems) {
size_t i;
for (i = 0; i < tcl->sz; ++i) {
for (size_t i = 0; i < tcl->sz; ++i) {
tcp_connection *otc = tcl->elems[i];
if (otc) {
if (addr_eq(&(otc->peer_addr), peer_addr)) {
@ -555,20 +572,24 @@ tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid
}
}
}
tcp_connection *tc = (tcp_connection *)calloc(sizeof(tcp_connection), 1);
tcp_connection *tc = (tcp_connection *)calloc(1, sizeof(tcp_connection));
if (!tc) {
return NULL;
}
addr_cpy(&(tc->peer_addr), peer_addr);
if (tid)
if (tid) {
memcpy(&(tc->tid), tid, sizeof(stun_tid));
}
tc->owner = a;
int found = 0;
bool found = false;
if (a->tcs.elems) {
size_t i;
for (i = 0; i < tcl->sz; ++i) {
for (size_t i = 0; i < tcl->sz; ++i) {
tcp_connection *otc = tcl->elems[i];
if (!otc) {
tcl->elems[i] = tc;
found = 1;
found = true;
break;
}
}
@ -576,7 +597,11 @@ tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid
if (!found) {
size_t old_sz_mem = a->tcs.sz * sizeof(tcp_connection *);
a->tcs.elems = (tcp_connection **)realloc(a->tcs.elems, old_sz_mem + sizeof(tcp_connection *));
tcp_connection **new_elems = realloc(a->tcs.elems, old_sz_mem + sizeof(tcp_connection *));
if (!new_elems) {
return NULL;
}
a->tcs.elems = new_elems;
a->tcs.elems[a->tcs.sz] = tc;
a->tcs.sz += 1;
tcl = &(a->tcs);
@ -587,39 +612,39 @@ tcp_connection *create_tcp_connection(uint8_t server_id, allocation *a, stun_tid
}
void delete_tcp_connection(tcp_connection *tc) {
if (tc) {
if (tc->done) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed tcp data connection: 0x%lx\n", __FUNCTION__,
(unsigned long)tc);
return;
if (!tc) {
return;
}
if (tc->done) {
TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "!!! %s: check on already closed tcp data connection: %p\n", __FUNCTION__, tc);
return;
}
tc->done = true;
clear_unsent_buffer(&(tc->ub_to_client));
IOA_EVENT_DEL(tc->peer_conn_timeout);
IOA_EVENT_DEL(tc->conn_bind_timeout);
allocation *a = (allocation *)(tc->owner);
if (a) {
ur_map *map = a->tcp_connections;
if (map) {
ur_map_del(map, (ur_map_key_type)(tc->id), NULL);
}
tc->done = 1;
clear_unsent_buffer(&(tc->ub_to_client));
IOA_EVENT_DEL(tc->peer_conn_timeout);
IOA_EVENT_DEL(tc->conn_bind_timeout);
allocation *a = (allocation *)(tc->owner);
if (a) {
ur_map *map = a->tcp_connections;
if (map) {
ur_map_del(map, (ur_map_key_type)(tc->id), NULL);
}
tcp_connection_list *tcl = &(a->tcs);
if (tcl->elems) {
size_t i;
for (i = 0; i < tcl->sz; ++i) {
if (tcl->elems[i] == tc) {
tcl->elems[i] = NULL;
break;
}
tcp_connection_list *tcl = &(a->tcs);
if (tcl->elems) {
for (size_t i = 0; i < tcl->sz; ++i) {
if (tcl->elems[i] == tc) {
tcl->elems[i] = NULL;
break;
}
}
}
IOA_CLOSE_SOCKET(tc->client_s);
IOA_CLOSE_SOCKET(tc->peer_s);
free(tc);
}
IOA_CLOSE_SOCKET(tc->client_s);
IOA_CLOSE_SOCKET(tc->peer_s);
free(tc);
}
tcp_connection *get_and_clean_tcp_connection_by_id(ur_map *map, tcp_connection_id id) {
@ -647,9 +672,7 @@ tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr) {
if (a && peer_addr) {
tcp_connection_list *tcl = &(a->tcs);
if (tcl->elems) {
size_t i;
size_t sz = tcl->sz;
for (i = 0; i < sz; ++i) {
for (size_t i = 0; i < tcl->sz; ++i) {
tcp_connection *tc = tcl->elems[i];
if (tc) {
if (addr_eq(&(tc->peer_addr), peer_addr)) {
@ -662,15 +685,16 @@ tcp_connection *get_tcp_connection_by_peer(allocation *a, ioa_addr *peer_addr) {
return NULL;
}
int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay) {
if (server_relay)
return 1;
if (a && peer_addr) {
return (get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr) != NULL);
bool can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int server_relay) {
if (server_relay) {
return true;
}
return 0;
if (a && peer_addr) {
return get_from_turn_permission_hashtable(&(a->addr_to_perm), peer_addr) != NULL;
}
return false;
}
//////////////// Unsent buffers //////////////////////
@ -678,8 +702,7 @@ int can_accept_tcp_connection_from_peer(allocation *a, ioa_addr *peer_addr, int
void clear_unsent_buffer(unsent_buffer *ub) {
if (ub) {
if (ub->bufs) {
size_t sz;
for (sz = 0; sz < ub->sz; sz++) {
for (size_t sz = 0; sz < ub->sz; sz++) {
ioa_network_buffer_handle nbh = ub->bufs[sz];
if (nbh) {
ioa_network_buffer_delete(NULL, nbh);
@ -706,8 +729,7 @@ void add_unsent_buffer(unsent_buffer *ub, ioa_network_buffer_handle nbh) {
ioa_network_buffer_handle top_unsent_buffer(unsent_buffer *ub) {
ioa_network_buffer_handle ret = NULL;
if (ub && ub->bufs && ub->sz) {
size_t sz;
for (sz = 0; sz < ub->sz; ++sz) {
for (size_t sz = 0; sz < ub->sz; ++sz) {
if (ub->bufs[sz]) {
ret = ub->bufs[sz];
break;
@ -719,8 +741,7 @@ ioa_network_buffer_handle top_unsent_buffer(unsent_buffer *ub) {
void pop_unsent_buffer(unsent_buffer *ub) {
if (ub && ub->bufs && ub->sz) {
size_t sz;
for (sz = 0; sz < ub->sz; ++sz) {
for (size_t sz = 0; sz < ub->sz; ++sz) {
if (ub->bufs[sz]) {
ub->bufs[sz] = NULL;
break;

Some files were not shown because too many files have changed in this diff Show More