[Xubuntu22.04] Try coTurn for WebRTC 1
Tags: coturn
Published: 2022-08-29 17:30:26

## Intro
I will try TURN server with WebRTC in this time.

* [coturn - GitHub](https://github.com/coturn/coturn/)

The main purpose of this project is to install and run the TURN server.
Next time, I will look at the detailed setup, etc. the next i

## Installation
### Build from source code(Failed)
Because there are no coTurn packages in PPA repositories, I tried building from the source code first.

* [INSTALL - coturn - GitHub](https://github.com/coturn/coturn/blob/master/INSTALL)
* [【WebRTC】「coTurn」の構築手順1 - プログラミングマガジン](http://www.code-magagine.com/?p=15992)

But when I tried executing "make", I would gotten an error.

```
mkdir -p build/obj
cc  -g  -Wall -Wno-deprecated-declarations -Wextra -Wformat-security -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Wcast-qual  -DTURN_HAS_DAEMON    -DTURN_NO_PROMETHEUS       -DINSTALL_PREFIX=/usr/local -DTURNDB=/usr/local/var/db/turndb -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ -I/usr/local/include/ -I/usr/local/include/  -c src/client/ns_turn_ioaddr.c -o build/obj/ns_turn_ioaddr.o
mkdir -p build/obj
cc  -g  -Wall -Wno-deprecated-declarations -Wextra -Wformat-security -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Wcast-qual  -DTURN_HAS_DAEMON    -DTURN_NO_PROMETHEUS       -DINSTALL_PREFIX=/usr/local -DTURNDB=/usr/local/var/db/turndb -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ -I/usr/local/include/ -I/usr/local/include/  -c src/client/ns_turn_msg_addr.c -o build/obj/ns_turn_msg_addr.o
mkdir -p build/obj
cc  -g  -Wall -Wno-deprecated-declarations -Wextra -Wformat-security -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Wcast-qual  -DTURN_HAS_DAEMON    -DTURN_NO_PROMETHEUS       -DINSTALL_PREFIX=/usr/local -DTURNDB=/usr/local/var/db/turndb -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ -I/usr/local/include/ -I/usr/local/include/  -c src/client/ns_turn_msg.c -o build/obj/ns_turn_msg.o
src/client/ns_turn_msg.c: In function ‘stun_produce_integrity_key_str’:
src/client/ns_turn_msg.c:260:21: warning: implicit declaration of function ‘FIPS_mode’ [-Wimplicit-function-declaration]
  260 |                 if (FIPS_mode()) {
      |                     ^~~~~~~~~
src/client/ns_turn_msg.c:260:21: warning: nested extern declaration of ‘FIPS_mode’ [-Wnested-externs]
src/client/ns_turn_msg.c: In function ‘stun_attr_add_integrity_str’:
src/client/ns_turn_msg.c:1855:12: warning: ‘hmac’ may be used uninitialized [-Wmaybe-uninitialized]
 1855 |         if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, hmac, shasize)<0)
      |            ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src/client/ns_turn_msg.c:1441:5: note: by argument 4 of type ‘const uint8_t *’ {aka ‘const unsigned char *’} to ‘stun_attr_add_str’ declared here
 1441 | int stun_attr_add_str(uint8_t* buf, size_t *len, uint16_t attr, const uint8_t* avalue, int alen) {
      |     ^~~~~~~~~~~~~~~~~
src/client/ns_turn_msg.c:1837:17: note: ‘hmac’ declared here
 1837 |         uint8_t hmac[MAXSHASIZE];
      |                 ^~~~
mkdir -p lib
ar -r lib/libturnclient.a build/obj/ns_turn_ioaddr.o build/obj/ns_turn_msg_addr.o build/obj/ns_turn_msg.o 
ar: lib/libturnclient.a を作成しています
pwd
/home/example/Documents/coturn
mkdir -p bin
cc  -g  -Wall -Wno-deprecated-declarations -Wextra -Wformat-security -Wnested-externs -Wstrict-prototypes  -Wmissing-prototypes -Wpointer-arith -Wcast-qual  -DTURN_HAS_DAEMON    -DTURN_NO_PROMETHEUS       -DINSTALL_PREFIX=/usr/local -DTURNDB=/usr/local/var/db/turndb -Isrc -Isrc/apps/common -Isrc/server -Isrc/client -Isrc/client++ -I/usr/local/include/ -I/usr/local/include/  src/apps/oauth/oauth.c src/apps/common/apputils.c src/apps/common/ns_turn_utils.c src/apps/common/stun_buffer.c -o bin/turnutils_oauth -Llib -lturnclient -Llib -lrt -lnsl -lresolv -lcrypto -lssl -levent_core -levent_extra -levent_openssl -levent_pthreads -levent  -Wl,-rpath,/usr/local/lib
/usr/bin/ld: lib/libturnclient.a(ns_turn_msg.o): in function `stun_produce_integrity_key_str':
/home/example/Documents/coturn/src/client/ns_turn_msg.c:260: undefined reference to `FIPS_mode'
collect2: error: ld returned 1 exit status
make: *** [Makefile:121: bin/turnutils_oauth] エラー 1
```

I tried [http://turnserver.open-sys.org/](http://turnserver.open-sys.org/downloads/) and cloning the [GitHub repository](https://github.com/coturn/coturn/), but I got the same results.

### Add unofficial PPA repositories
After that, I decided to add PPA repositories.

```
sudo add-apt-repository ppa:ubuntuhandbook1/coturn
sudo apt update
sudo apt install coturn
```

* [How to install Coturn (TURN / STUN Server) in Ubuntu 22.04 via PPA - OSS Malta](https://ossmalta.eu/how-to-install-coturn-turn-stun-server-in-ubuntu-22-04-via-ppa/)

Finally, I installed coTurn ver.4.5.2-1.

## Edit configurations and start coTurn
To start coTurn, I uncomment "/etc/default/coturn" and execute "sudo systemctl start coturn".

#### coturn
```conf
#
# Uncomment it if you want to have the turnserver running as 
# an automatic system service daemon
#
TURNSERVER_ENABLED=1
```

After that, I edit "/etc/turnserver.conf".
Because I don't have any domains, so I use IP address instead of them this time, 

#### turnserver.conf
```conf
...
# TURN listener port for UDP and TCP (Default: 3478).
# Note: actually, TLS & DTLS sessions can connect to the
# "plain" TCP & UDP port(s), too - if allowed by configuration.
#
listening-port=3478
...
# Uncomment to run TURN server in 'extra' verbose mode.
# This mode is very annoying and produces lots of output.
# Not recommended under normal circumstances.
#
Verbose

# Uncomment to use fingerprints in the TURN messages.
# By default the fingerprints are off.
#
fingerprint

# Uncomment to use long-term credential mechanism.
# By default no credentials mechanism is used (any user allowed).
#
lt-cred-mech
...
# 'Static' user accounts for the long term credentials mechanism, only.
# This option cannot be used with TURN REST API.
# 'Static' user accounts are NOT dynamically checked by the turnserver process,
# so they can NOT be changed while the turnserver is running.
#
#user=username1:key1
#user=username2:key2
# OR:
user=username1:password1
...
# The default realm to be used for the users when no explicit
# origin/realm relationship is found in the database, or if the TURN
# server is not using any database (just the commands-line settings
# and the userdb file). Must be used with long-term credentials
# mechanism or with TURN REST API.
#
# Note: If the default realm is not specified, then realm falls back to the host domain name.
#       If the domain name string is empty, or set to '(None)', then it is initialized as an empty string.
#
realm=192.168.XX.YYY
...
# Certificate file.
# Use an absolute path or path relative to the
# configuration file.
# Use PEM file format.
#
cert=/home/example/local_cert.pem

# Private key file.
# Use an absolute path or path relative to the
# configuration file.
# Use PEM file format.
#
pkey=/home/example/local_key.pem
...
# Option to set the log file name.
# By default, the turnserver tries to open a log file in
# /var/log, /var/tmp, /tmp and the current directory
# (Whichever file open operation succeeds first will be used).
# With this option you can set the definite log file name.
# The special names are "stdout" and "-" - they will force everything
# to the stdout. Also, the "syslog" name will force everything to
# the system log (syslog).
# In the runtime, the logfile can be reset with the SIGHUP signal
# to the turnserver process.
#
log-file=/var/tmp/turn.log
...
# Option to suppress STUN functionality, only TURN requests will be processed.
# Run as TURN server only, all STUN requests will be ignored.
# By default, this option is NOT set.
#
no-stun
...
```

* [INSTALL - coturn - GitHub](https://github.com/coturn/coturn/blob/master/INSTALL)
* [README.turnserver - coturn - GitHub](https://github.com/coturn/coturn/blob/master/README.turnserver)
* [How to setup and configure TURN server using coTURN? - Metered blog](https://www.metered.ca/blog/coturn/)
* [How to Set up Coturn TURN Server for Spreed WebRTC - LinuxBabe](https://www.linuxbabe.com/linux-server/install-coturn-turn-server-spreed-webrtc)
* [WebRTC のための TURN サーバ - panda's tech note ](https://ja.tech.jar.jp/webrtc/turn.html)
* [systemd - ArchWiki](https://wiki.archlinux.org/title/systemd)

## Try
All the clients used in this case are connected to the same network, so they don't normally pass through the TURN server.
Thus, I add "iceTransportPolicy" to force passing through it.

#### webrtc.controller.ts
```ts
...
    public connect() {
        if (this.webcamStream == null) {
            console.error("Local video was null");
            return;
        }
        this.peerConnection = new RTCPeerConnection({
            iceServers: [{
                urls: "turn:192.168.XX.YYY:3478",
                username: "username1",
                credential: "password1",
            }],
            // Force using STUN or TURN servers. 
            iceTransportPolicy: "relay"
        });
...
```

#### ICE candidate from clients
```
{"candidate":"candidate:1070431248 1 udp 41885439 192.168.XX.YYY 61498 typ relay raddr 0.0.0.0 rport 0 generation 0 ufrag U+dE network-id 1","sdpMid":"0","sdpMLineIndex":0}
```

* [RTCPeerConnection() - MDN](https://developer.mozilla.org/en-US/docs/Web/API/RTCPeerConnection/RTCPeerConnection)