Skip to content

Collection of scripts and configuration files for running an on-premise ODIN server

Notifications You must be signed in to change notification settings

4Players/odin-server

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

65 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ODIN

ODIN Server

v1.5.9

ODIN is a versatile cross-platform Software Development Kit (SDK) engineered to seamlessly integrate real-time voice chat into multiplayer games, applications, and websites. Regardless of whether you're employing a native application or your preferred web browser, ODIN simplifies the process of maintaining connections with your significant contacts. Through its intuitive interface and robust functionality, ODIN enhances interactive experiences, fostering real-time engagement and collaboration across various digital platforms.

Online Documentation

This repository provides a collection of scripts and configuration files for running an on-premise ODIN server. The ODIN server is a Selective Forwarding Unit (SFU), which connects users in mutual rooms by acting as a relay for media and data.

flowchart BT
  subgraph Server
    R2("Room #quot;Team 1#quot;")
    R1("Room #quot;World Map#quot;")
    R3("Room #quot;Team 2#quot;")
  end

  C1("Client 1")
  C2("Client 2")
  C3("Client 3")
  C4("Client 4")

  C1 --> R1 & R2
  C2 --> R1 & R2
  C3 --> R1 & R3
  C4 --> R1 & R3
Loading

Configuration

The server is configured using a configuration file and optional command-line arguments.

Note: For local testing, using mkcert is recommended to generate certificates.

Command-Line arguments

Option Description Default Value
--config Path to the config file config.toml
--license Path to the license file license.toml

Here's an example on how to start the server using a custom config path.

./grid --config /etc/grid/config.toml

The config.toml file

You can change the behavior of your ODIN server by modifying its configuration file called config.toml, which uses the TOML format.

public_address Required

The FQDN and port number where the server can be reached from the Internet.

public_address = "localhost:4433"

The [supervisor] section

The [supervisor] section allows you to attach your server instance to an external gateway, which can be used for scalability in your hosting infrastructure. It is expected to be specified on the root level.

url Required

The full web address of the supervisor to contact and send reports to.

url = "https://localhost:7000/internal"

report_interval

The time in milliseconds between consecutive reports to the supervisor.

report_interval = 5_000

no_warmup

When true, the server wait for one report cycle before starting to send reports to the supervisor.

no_warmup = false

The [authorization] section

The ODIN server uses JSON Web Tokens (JWT) with EdDSA/Ed25519 signature for client authorization. The [authorization] section can be used to change the behavior of this process.

allow_unsigned

Then true, the server will accept logins using unsigned tokens. It is strongly recommended, that you do NOT enable this in a production environment.

allow_unsigned = false

leeway

The number of milliseconds a login token can be before or beyond its valid time period and still pass.

leeway = 5_000

The [[authorization.keys]] section

The [[authorization.keys]] section is used to define a list of keys allowed to sign login tokens. When using a [supervisor], this section can be omitted as it will be automatically generated by the gateway.

[[authorization.keys]]
kid = "Afkwfu4BVHDh"
kty = "OKP"
crv = "Ed25519"
x = "a5J2bhmU7vsY0LrW1zt56iUdmhRUNz7Pl9eBoCy29d8"
d = "5FYw1qdABjE0qEKEe821L7UPl_DZfO-PavpaiLsGDR0"

Note: You can use the @4players/odin-cli package to generate this section for you.

The [database] section

The [database] section is used to enable and configure an optional database backend using Redis to store room/peer state information.

address Required

FQDN and port number of the database server to use.

address = "127.0.0.1:6379"

use_tls

Establish a secure TLS connection.

use_tls = true

username

Optional username to use ACL style authentication when connecting to the server (requires a password).

username = "admin"

password

Optional password to use when connecting to the server.

password = "secret"

server_id

Optional identifier of the server to use when adding state information to the database.

server_id = "foo"

command_timeout

Optional command timeout after which commands in the pipeline will fail.

command_timeout = 500

The [quic] section

The [quic] section is used to enable and configure the HTTP/3 socket listener for native ODIN core SDK clients.

public_address_override

Optional FQDN and port number where the server can be reached from the Internet specifically for QUIC clients.

public_address_override = "localhost:4433"

binding Required

The socket where incoming connections are accepted from.

binding = "0.0.0.0:4433"

certificate_file Required

The path to a PEM-encoded leaf certificate followed by optional intermediate certificates.

certificate_file = "fullchain.pem"

privatekey_file Required

The path to a PEM-encoded private key.

privatekey_file = "privkey.pem"

migration

When enabled, the server accept IP address changes from clients.

migration = true

keep_alive_interval

Time in milliseconds between keep-alive packets sent by the server.

keep_alive_interval = 5_000 # ms

idle_timeout

Drop a connection if no packets have been received in this time span in milliseconds.

idle_timeout = 30_000 # ms

pre_send_timeout

The maximum time the sender waits for a packet to be inserted into the send buffer.

pre_send_timeout = 500 # ms

connect_timeout

The maximum time in milliseconds a connection can take to finish the HTTP/3 setup, until a client is created.

connect_timeout = 1_000 # ms

no_peers_timeout

The maximum time in milliseconds a client can stay connected, after leaving all rooms.

no_peers_timeout = 1_000 # ms

The [http] section

The [http] section is used to enable and configure the socket listener for ODIN web SDK clients.

public_address_override

Optional FQDN and port number where the server can be reached from the Internet specifically for WebSocket clients.

public_address_override = "localhost:4433"

binding Required

The socket where incoming connections are accepted from.

binding = "0.0.0.0:4433"

certificate_file Required

The path to a PEM-encoded leaf certificate followed by optional intermediate certificates.

certificate_file = "fullchain.pem"

privatekey_file Required

The path to a PEM-encoded private key.

privatekey_file = "privkey.pem"

webrtc_candidates

The list of IP addresses to be offered as candidates.

webrtc_candidates = ["127.0.0.1", "::1"]

webrtc_binding

The socket where WebRTC connections are accepted from.

webrtc_binding = "0.0.0.0:8844"

timeout

Drop connections after this much inactivity in milliseconds.

timeout = 10_000 # ms

ping_interval

Send a ping to the client using this interval in milliseconds.

ping_interval = 5_000 # ms

no_peers_timeout

The maximum time in milliseconds a client can stay connected, after leaving all rooms.

no_peers_timeout = 1_000 # ms

The [log.terminal] section

The [log.terminal] section is used to configure terminal specific logging options.

verbosity Required

The verbosity level [0-3] to define how much information should be written to logs.

verbosity = 1

format

The output format for terminal logs. Available options are json and text.

format = "text"

filters

Optional list of modules filtered from logs to prevent unnecessary noise, except for error messages.

filters = ["webrtc", "webrtc_ice"]

The [log.loki] section

The [log.loki] section is used to configure Grafana Loki specific logging options.

url Required

The base URL where the external log aggregation system is running.

url = "https://localhost/"

labels

Labels to describe the log stream.

labels = {job = "foo", instance = "bar"}

The [metrics] section

The [metrics] section is used to enable and configure a Prometheus metrics listener.

binding Required

The socket where incoming connections are accepted from.

binding = "0.0.0.0:9000"

idle_timeout

How long after the last change a metric value is reported.

idle_timeout = 3_600_000 # ms

global_labels

Labels that are added to all reported metrics.

global_labels = {deployment = "foo"}

allowed

List of IP subnets that are allowed to query metrics from the server.

allowed = ["0.0.0.0/0"]

The [limit] section

The [limit] section is used to configure concurrency limits.

max_clients

The maximum number of concurrent clients accepted by the server.

max_clients = 25

max_rooms

The maximum number of concurrent rooms accepted by the server.

max_rooms = 25

max_peers

The maximum number of concurrent peers accepted by the server.

max_peers = 25

The [limit.network] section

The [limit.network] section is used to configure network rate limits.

incoming_media_packets

The number of packets a media can send to the server every second.

incoming_media_packets = {rate = 50, capacity = 100}

The [limit.peer] section

The [limit.peer] section is used to configure limits per individual peer.

incoming_messages

The number of command packets of a peer that are processed by the server every second.

incoming_messages = {rate = 10, capacity = 50, overflow = 20}

concurrent_streams

The number of concurrent audio streams [0-8] a peer can receive. A value of 0 means unlimited.

concurrent_streams = 8

medias

The number of medias a peer can create.

medias = 5

The [telemetry] section

The [telemetry] section is used to enable a telemetry client used for licensing.

address Required

The web address of the telemetry server to contact and send reports to.

address = "https://localhost/"

interval

The interval in milliseconds how often the telemetry data is being sent.

interval = 5_000 # ms

max_consecutive_failures

When set, this defines the maximum number of times sending telemetry data can fail before the server shuts down.

max_consecutive_failures = 4

data

Optional data from the [license] section to send to the telemetry server.

data = [
  "LicenseValidUntil",
  "LicenseLicensee",
  "LicenseSerialNumber",
  "LicenseIssuer",
  "LicenseClientLimit",
  "LicenseClientUsage",
  "LicensePeerLimit",
  "LicensePeerUsage",
  "LicenseRoomLimit",
  "LicenseRoomUsage"
]

The [http_client] section

The optional [http_client] section is used to configure the behavior of the internal HTTP client for outbound requests.

proxy Required

Optional HTTP/HTTPS proxy server to use for outbound requests.

proxy = "https://localhost:3128"

accept_invalid_certificates

Allows acceptance of SSL/TLS certificates signed by unknown authorities during outbound requests.

accept_invalid_certificates = false

The [license] section

The optional [license] section is used to identify the licensee of the ODIN server. This section is used in a separate license.toml file.

signature Required

The signature of the license used to verify its validity.

signature = ""

issuer

An optional field to identify the issuer of the license.

issuer = "4Players"

licensee

An optional field to identify the licensee. Usually, this is your 4Players customer number (CID).

licensee = "622012345"

serial_number

An optional serial number of the license. Usually, this is the ID of your on-premise hosting subscription project.

serial_number = "b0FBTWZ2Rj3OY25uZWtYRlpoekVBUT09"

valid_until

An optional expiration date for the license. When set, the server can't be used after his date.

valid_until = 1987-07-05T17:45:00Z

The [internal] section

The [internal] section is used to configure internal settings for debugging.

log_hanging_api_calls

A debug option to emit warnings if RPC calls take longer then the threshold in milliseconds.

log_hanging_api_calls = 1_000 # ms

log_rejected_api_calls

A debug option to emit warnings if RPC calls are rejected.

log_rejected_api_calls = false

Examples

Create a configuration file and use the grid executable to start the ODIN server.

Minimal config.toml for Supervised Server

When running the ODIN server in combination with a gateway, you only need to specify the web address of the supervisor. The server will register with the supervisor and automatically receive recommended settings, which will be used to extend the local config.toml file.

The recommended configuration of the gateway can be defined here.

public_address = "server.tld:4433"

[supervisor]
url = "https://username:password@localhost:7000/internal"

Minimal config.toml for Standalone Server

When running the ODIN server in standalone mode, you need to specify at least one JWK used for authorization pair as well as the binding and certificate configuration for incoming client connections.

public_address = "server.tld:4433"

[[authorization.keys]]
kid = "Afkwfu4BVHDh"
kty = "OKP"
crv = "Ed25519"
x = "a5J2bhmU7vsY0LrW1zt56iUdmhRUNz7Pl9eBoCy29d8"
d = "5FYw1qdABjE0qEKEe821L7UPl_DZfO-PavpaiLsGDR0"

[quic]
binding = "0.0.0.0:4433"
certificate_file = "fullchain.pem"
privatekey_file = "privkey.pem"

Troubleshooting

Contact us through the listed methods below to receive answers to your questions and learn more about ODIN.

Discord

Join our official Discord server to chat with us directly and become a part of the 4Players ODIN community.

Join us on Discord

Twitter

Have a quick question? Tweet us at @ODIN4Players and we’ll help you resolve any issues.

Email

Don’t use Discord or Twitter? Send us an email and we’ll get back to you as soon as possible.

About

Collection of scripts and configuration files for running an on-premise ODIN server

Topics

Resources

Stars

Watchers

Forks