JSON Example
```json
{
"log": {
"level": "warn",
"output": "realm.log"
},
"network": {
"no_tcp": false,
"use_udp": true
},
"endpoints": [
{
"listen": "0.0.0.0:5000",
"remote": "1.1.1.1:443"
},
{
"listen": "0.0.0.0:10000",
"remote": "www.google.com:443"
}
]
}
```
[See more examples here](./examples).
## Overview
```shell
├── log
│ ├── level
│ └── output
├── dns
│ ├── mode
│ ├── protocol
│ ├── nameservers
│ ├── min_ttl
│ ├── max_ttl
│ └── cache_size
├── network
│ ├── no_tcp
│ ├── use_udp
│ ├── ipv6_only
│ ├── tcp_timeout
│ ├── udp_timeout
│ ├── tcp_keepalive
│ ├── tcp_keepalive_probe
│ ├── send_mptcp
│ ├── accept_mptcp
│ ├── send_proxy
│ ├── send_proxy_version
│ ├── accept_proxy
│ └── accept_proxy_timeout
└── endpoints
├── listen
├── remote
├── extra_remotes
├── balance
├── through
├── interface
├── listen_interface
├── listen_transport
├── remote_transport
└── network->
```
You should provide at least [endpoint.listen](#endpointlisten-string) and [endpoint.remote](#endpointremote-string), the left fields will take their default values.
Option priority: cmd override > endpoint config > global config.
### endpoint
#### endpoint.listen: string
Local address, supported formats:
- ipv4:port
- ipv6:port
#### endpoint.remote: string
Remote address, supported formats:
- ipv4:port
- ipv6:port
- example.com:port
#### endpoint.extra_remotes: string array
Extra remote address, same as endpoint.remote above.
#### endpoint.balance: string
Require `balance` feature.
Load balance strategy and weights of remote peers.
Format:
```bash
$strategy: $weight1, $weight2, ...
```
Where `remote` is used as default backend server, and `extra_remotes` are used as backups.
Available algorithms (provided by [realm_lb](./realm_lb/)):
- iphash
- roundrobin
Example:
```toml
[[endpoints]]
remote = "a:443"
extra_remotes = ["b:443", "c:443"]
balance = "roundrobin: 4, 2, 1"
```
The weight of [a, b, c] is [4, 2, 1] in turn.
#### endpoint.through: string
TCP: Bind a specific `ip` before opening a connection.
UDP: Bind a specific `ip` or `address` before sending packet.
Supported formats:
- ipv4/ipv6 (tcp/udp)
- ipv4/ipv6:port (udp)
#### endpoint.interface: string
Bind to a specific interface for outgoing traffics.
#### endpoint.listen_interface: string
Bind to a specific interface for incoming traffics.
#### endpoint.listen_transport: string
Require `transport` feature.
See [Kaminari Options](https://github.com/zephyrchien/kaminari#options).
#### endpoint.remote_transport: string
Require `transport` feature.
See [Kaminari Options](https://github.com/zephyrchien/kaminari#options).
#### endpoint.network
The same as [network](#network), override global options.
### log
#### log.level: string
values:
- off
- error
- warn
- info
- debug
- trace
default: off
#### log.output: string
values:
- stdout
- stderr
- path (e.g. `/var/log/realm.log`)
default: stdout
### dns
Require `trust-dns` feature.
#### dns.mode: string
Dns resolve strategy.
values:
- ipv4_only
- ipv6_only
- ipv4_then_ipv6
- ipv6_then_ipv4
- ipv4_and_ipv6
default: ipv4_and_ipv6
#### dns.protocol: string
Dns transport protocol.
values:
- tcp
- udp
- tcp_and_udp
default: tcp_and_udp
#### dns.nameservers: string array
Custom upstream servers.
format: ["server1", "server2" ...]
default:
If on **unix/windows**, read from the default location.(e.g. `/etc/resolv.conf`).
Otherwise, use google's public dns(`8.8.8.8:53`, `8.8.4.4:53` and `2001:4860:4860::8888:53`, `2001:4860:4860::8844:53`).
#### dns.min_ttl: unsigned int
The minimum lifetime of a positive dns cache.
default: 0
#### dns.max_ttl: unsigned int
The maximum lifetime of a positive dns cache.
default: 86400 (1 day)
#### dns.cache_size: unsigned int
The maximum count of dns cache.
default: 32
### network
#### network.no_tcp: bool
Do not start a tcp relay.
default: false
#### network.use_udp: bool
~~Require `udp` feature~~
Start listening on a udp endpoint and forward packets to the remote peer.
It will dynamically allocate local endpoints and establish udp associations. Once timeout, the endpoints will be deallocated and the association will be terminated. See also: [network.udp_timeout](#networkudp_timeout-unsigned-int).
Due to the receiver side not limiting access to the association, the relay works like a full-cone NAT.
default: false
#### network.ipv6_only: bool
Disable ipv4-mapped-ipv6 when binding to an ipv6 address.
E.g.:
`[::0]:port` with (ipv6_only=false) binds to `*:port`
`[::0]:port` with (ipv6_only=true) binds to `[::]:port`
default: false
#### ~~network.zero_copy: bool~~ deprecated
~~Require `zero-copy` feature.~~
~~Use `splice` instead of `send/recv` while handing tcp connection. This will save a lot of memory copies and context switches.~~
~~default: false~~
#### ~~network.fast_open: bool~~ deprecated
~~Require `fast-open` feature.~~
~~It is not recommended to enable this option, see [The Sad Story of TCP Fast Open](https://squeeze.isobar.com/2019/04/11/the-sad-story-of-tcp-fast-open/).~~
~~default: false~~
#### network.tcp_timeout: unsigned int
This is **connect** timeout. An attempt to connect to a remote peer fails after waiting for a period of time.
To disable timeout, you need to explicitly set timeout value to 0.
default: 5
#### network.udp_timeout: unsigned int
Terminate udp association after `timeout`.
The timeout value must be properly configured in case of memory leak. Do not use a large `timeout`!
default: 30
#### network.tcp_keepalive: unsigned int
TCP Keepalive interval.
On Linux, this is equivalent to setting both `net.ipv4.tcp_keepalive_time` and `net.ipv4.tcp_keepalive_intvl`.
To use system's tcp keepalive interval, you need to explicitly set this option to 0.
default: 15
#### network.tcp_keepalive_probe: unsigned int
TCP Keepalive retries.
On Linux, this is equivalent to `ipv4.tcp_keepalive_probes`.
default: 3
#### network.send_mptcp: bool
Enable MPTCP outbound connections on Linux.
Requires a higher kernel version(>5.6) with `net.mptcp.enabled=1`.
See also [Path Manager](https://www.mptcp.dev/pm.html) guidelines.
default: false
#### network.accept_mptcp: bool
Enable MPTCP inbound connections on Linux.
default: false
#### network.send_proxy: bool
Require `proxy` feature.
Send haproxy PROXY header once the connection established. Both `v1` and `v2` are supported, see [send_proxy_version](#networksend_proxy_version-unsigned-int).
You should make sure the remote peer also speaks proxy-protocol.
default: false
#### network.send_proxy_version: unsigned int
Require `proxy` feature.
This option has no effect unless [send_proxy](#networksend_proxy-bool) is enabled.
value:
- 1
- 2
default: 2
#### network.accept_proxy: bool
Require `proxy` feature.
Wait for a PROXY header once the connection established.
If the remote sender does not send a `v1` or `v2` header before other contents, the connection will be closed.
default: false
#### network.accept_timeout: unsigned int
Require `proxy` feature.
Wait for a PROXY header within a period of time, otherwise close the connection.
default: 5.