one-d-wide / yggdrasil-jumper

Reduce latency of a connection over yggdrasil network
GNU General Public License v3.0
28 stars 4 forks source link
nat-traversal peer-to-peer yggdrasil yggdrasil-network

Yggdrasil-jumper

Yggdrasil-Jumper is an independent project that aims to transparently reduce latency of a connection over Yggdrasil network, utilizing NAT traversal to bypass intermediary nodes. It periodically probes for active sessions and automatically establishes direct peerings over internet with remote nodes running Yggdrasil-Jumper without requiring any firewall configuration or port mapping.

Features

How it works

By default, yggdrasil-go routes data only through explicitly connected peers and doesn't attempt to reach other nodes accessible over the internet. Therefore, path usually contains 1-2 intermediary nodes, namely public peers of both sides. If both you and your peer use internet, you can send traffic directly (aka peer-to-peer), thus reducing latency.

Usage

Jumper can run without additional configuration. All it needs is access to Admin API of the router and to the IP network.

$ yggdrasil-jumper --loglevel info # off/error/warn/info/debug
...

It may be helpful to know what the defaults are.

$ yggdrasil-jumper --print-default
...
# List of possible admin socket locations
yggdrasil_admin_listen = [
  "unix:///var/run/yggdrasil/yggdrasil.sock",
  "unix:///var/run/yggdrasil.sock",
  "tcp://localhost:9001",
]
...
# List of allowed yggdrasil peer addresses
# Uncomment to apply
#whitelist = [ ]
...
# List of peering protocols
# Supported are "tcp", "quic", "tls"
yggdrasil_protocols = [ "tcp", "quic" ]

# List of yggdrasil listen addresses
# Known in the yggdrasil config as `Listen`
yggdrasil_listen = [ ]
...
# Default connect/listen port on yggdrasil network
listen_port = 4701
...
# List of STUN servers
stun_servers = [
  ...
]
...

You can also overwrite some if needed.

$ yggdrasil-jumper --config <path> # standard input is read if path is "-"
...

Installation

Details

External address lookup In order to know what address to use with [NAT traversal], jumper must know self external internet address and port. This task is performed using [STUN] protocol with TCP extension, hence not every [STUN] server is supported. [STUN] standard is quite broad, but jumper utilities only address lookup feature. You can check compatibility using `stun-test` binary from this repository. ```shell $ cargo build --bin stun-test --release $ # ./target/release/stun-test ``` `stun-test` takes network protocol and [STUN] server(s) as argument and outputs resolved address. ```shell $ stun-test --tcp --print-servers stunserver.stunprotocol.org:3478 stunserver.stunprotocol.org:3478 244.13.30.107:28674 ``` You can also take servers from hardcoded defaults or your configuration. ```shell $ stun-test --tcp --default 244.13.30.107:28674 ... ``` If `stun-test` fails to connect to any server it will print error and exit with code `1`. ```shell $ stun-test --tcp stunserver.stunprotocol.org:3478 127.0.0.1:3478 244.13.30.107:28674 ERROR While resolving {server=127.0.0.1:3478}: Failed to connect: Connection refused ``` It also checks whether all servers return same address. You can skip this check by passing `--no-check` argument. ```shell $ stun-test --tcp stunserver.stunprotocol.org:3478 false.resolver 244.13.30.107:28674 ERROR While resolving {server=false.resolver}: {received=0.0.0.0:0}: Previously resolved addresses do not match ```
Establishing direct connection over the internet NAT traversal procedure is described in [this paper](https://bford.info/pub/net/p2pnat), here is a short summary: - Create and bind listen and connection sockets to the same port (using `SO_REUSEADDR` and `SO_REUSEPORT` flags). - Lookup self external address and port. - Exchange external addresses with the peer. - Try to connect to the peer and listen for connection simultaneously.