{"id":13400462,"url":"https://github.com/pojntfx/weron","last_synced_at":"2025-12-15T18:04:27.552Z","repository":{"id":38885023,"uuid":"464642335","full_name":"pojntfx/weron","owner":"pojntfx","description":"Overlay networks based on WebRTC.","archived":false,"fork":false,"pushed_at":"2025-04-22T00:29:26.000Z","size":893,"stargazers_count":1867,"open_issues_count":9,"forks_count":64,"subscribers_count":27,"default_branch":"main","last_synced_at":"2025-04-22T01:20:43.890Z","etag":null,"topics":["golang","nat","networking","overlay-network","p2p","pion","tuntap","vpn","webrtc"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pojntfx.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-02-28T20:58:50.000Z","updated_at":"2025-04-22T00:10:14.000Z","dependencies_parsed_at":"2023-09-24T03:06:59.627Z","dependency_job_id":"bf295da1-4bc9-4dd4-b486-ffa76af61ad6","html_url":"https://github.com/pojntfx/weron","commit_stats":null,"previous_names":["pojntfx/webrtcfd"],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fweron","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fweron/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fweron/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pojntfx%2Fweron/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pojntfx","download_url":"https://codeload.github.com/pojntfx/weron/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254355335,"owners_count":22057354,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["golang","nat","networking","overlay-network","p2p","pion","tuntap","vpn","webrtc"],"created_at":"2024-07-30T19:00:52.318Z","updated_at":"2025-12-15T18:04:27.537Z","avatar_url":"https://github.com/pojntfx.png","language":"Go","funding_links":[],"categories":["Go","webrtc"],"sub_categories":[],"readme":"\u003cimg alt=\"Project icon\" style=\"vertical-align: middle;\" src=\"./docs/icon.svg\" width=\"128\" height=\"128\" align=\"left\"\u003e\n\n# weron\n\nOverlay networks based on WebRTC.\n\n\u003cbr/\u003e\n\n[![hydrun CI](https://github.com/pojntfx/weron/actions/workflows/hydrun.yaml/badge.svg)](https://github.com/pojntfx/weron/actions/workflows/hydrun.yaml)\n[![Docker CI](https://github.com/pojntfx/weron/actions/workflows/docker.yaml/badge.svg)](https://github.com/pojntfx/weron/actions/workflows/docker.yaml)\n![Go Version](https://img.shields.io/badge/go%20version-%3E=1.18-61CFDD.svg)\n[![Go Reference](https://pkg.go.dev/badge/github.com/pojntfx/weron.svg)](https://pkg.go.dev/github.com/pojntfx/weron)\n[![TypeScript docs](https://img.shields.io/badge/TypeScript%20-docs-blue.svg)](https://pojntfx.github.io/weron)\n[![Matrix](https://img.shields.io/matrix/weron:matrix.org)](https://matrix.to/#/#weron:matrix.org?via=matrix.org)\n\n## Overview\n\nweron provides lean, fast \u0026 secure overlay networks based on WebRTC.\n\nIt enables you to:\n\n- **Access nodes behind NAT**: Because weron uses WebRTC to establish connections between nodes, it can easily traverse corporate firewalls and NATs using STUN, or even use a TURN server to tunnel traffic. This can be very useful to for example SSH into your homelab without forwarding any ports on your router.\n- **Secure your home network**: Due to the relatively low overhead of WebRTC in low-latency networks, weron can be used to secure traffic between nodes in a LAN without a significant performance hit.\n- **Join local nodes into a cloud network**: If you run for example a Kubernetes cluster with nodes based on cloud instances but also want to join your on-prem nodes into it, you can use weron to create a trusted network.\n- **Bypass censorship**: The underlying WebRTC suite, which is what popular videoconferencing tools such as Zoom, Teams and Meet are built on, is hard to block on a network level, making it a valuable addition to your toolbox for bypassing state or corporate censorship.\n- **Write your own peer-to-peer protocols**: The simple API makes writing distributed applications with automatic reconnects, multiple datachannels etc. easy.\n\n## Installation\n\n### Library\n\nYou can add weron to your Go project by running the following:\n\n```shell\n$ go get github.com/pojntfx/weron/...@latest\n```\n\n### Containerized\n\nYou can get the OCI image like so:\n\n```shell\n$ podman pull ghcr.io/pojntfx/weron\n```\n\n### Natively\n\nStatic binaries are available on [GitHub releases](https://github.com/pojntfx/weron/releases).\n\nOn Linux, you can install them like so:\n\n```shell\n$ curl -L -o /tmp/weron \"https://github.com/pojntfx/weron/releases/latest/download/weron.linux-$(uname -m)\"\n$ sudo install /tmp/weron /usr/local/bin\n$ sudo setcap cap_net_admin+ep /usr/local/bin/weron # This allows rootless execution\n```\n\nOn macOS, you can use the following:\n\n```shell\n$ curl -L -o /tmp/weron \"https://github.com/pojntfx/weron/releases/latest/download/weron.darwin-$(uname -m)\"\n$ sudo install /tmp/weron /usr/local/bin\n```\n\nOn Windows, the following should work (using PowerShell as administrator):\n\n```shell\nPS\u003e Invoke-WebRequest https://github.com/pojntfx/weron/releases/latest/download/weron.windows-x86_64.exe -OutFile \\Windows\\System32\\weron.exe\n```\n\nYou can find binaries for more operating systems and architectures on [GitHub releases](https://github.com/pojntfx/weron/releases).\n\n## Tutorial\n\n\u003e TL;DR: Join a layer 3 (IP) overlay network on the hosted signaling server with `sudo weron vpn ip --community mycommunity --password mypassword --key mykey --ips 2001:db8::1/32,192.0.2.1/24` and a layer 2 (Ethernet) overlay network with `sudo weron vpn ethernet --community mycommunity --password mypassword --key mykey`\n\n### 1. Start a Signaling Server with `weron signaler`\n\nThe signaling server connects peers with each other by exchanging connection information between them. It also manages access to communities through the `--password` flag of clients and can maintain persistent communities even after all peers have disconnected.\n\nWhile it is possible and reasonably private (in addition to TLS, connection information is encrypted using the `--key` flag of clients) to use the hosted signaling server at `wss://weron.up.railway.app/`, hosting it yourself has many benefits, such as lower latency and even better privacy.\n\nThe signaling server can use an in-process broker with an in-memory database or Redis and PostgreSQL; for production use the latter configuration is strongly recommended, as it allows you to easily scale the signaling server horizontally. This is particularly important if you want to scale your server infrastructure across multiple continents, as intra-cloud backbones usually have lower latency than residential connections, which reduces the amount of time required to connect peers with each other.\n\n\u003cdetails\u003e\n  \u003csummary\u003eExpand containerized instructions\u003c/summary\u003e\n\n```shell\n$ sudo podman network create weron\n\n$ sudo podman run -d --restart=always --label \"io.containers.autoupdate=image\" --name weron-postgres --network weron -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=weron_communities postgres\n$ sudo podman generate systemd --new weron-postgres | sudo tee /lib/systemd/system/weron-postgres.service\n\n$ sudo podman run -d --restart=always --label \"io.containers.autoupdate=image\" --name weron-redis --network weron redis\n$ sudo podman generate systemd --new weron-redis | sudo tee /lib/systemd/system/weron-redis.service\n\n$ sudo podman run -d --restart=always --label \"io.containers.autoupdate=image\" --name weron-signaler --network weron -p 1337:1337 -e DATABASE_URL='postgres://postgres@weron-postgres:5432/weron_communities?sslmode=disable' -e REDIS_URL='redis://weron-redis:6379/1' -e API_PASSWORD='myapipassword' ghcr.io/pojntfx/weron:unstable weron signaler\n$ sudo podman generate systemd --new weron-signaler | sudo tee /lib/systemd/system/weron-signaler.service\n\n$ sudo systemctl daemon-reload\n\n$ sudo systemctl enable --now weron-postgres\n$ sudo systemctl enable --now weron-redis\n$ sudo systemctl enable --now weron-signaler\n\n$ sudo firewall-cmd --permanent --add-port=1337/tcp\n$ sudo firewall-cmd --reload\n```\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n  \u003csummary\u003eExpand native instructions\u003c/summary\u003e\n\n```shell\nsudo podman run -d --restart=always --label \"io.containers.autoupdate=image\" --name weron-postgres -e POSTGRES_HOST_AUTH_METHOD=trust -e POSTGRES_DB=weron_communities -p 127.0.0.1:5432:5432 postgres\nsudo podman generate systemd --new weron-postgres | sudo tee /lib/systemd/system/weron-postgres.service\n\nsudo podman run -d --restart=always --label \"io.containers.autoupdate=image\" --name weron-redis -p 127.0.0.1:6379:6379 redis\nsudo podman generate systemd --new weron-redis | sudo tee /lib/systemd/system/weron-redis.service\n\nsudo tee /etc/systemd/system/weron-signaler.service\u003c\u003c'EOT'\n[Unit]\nDescription=weron Signaling Server\nAfter=weron-postgres.service weron-redis.service\n\n[Service]\nExecStart=/usr/local/bin/weron signaler --verbose=7\nEnvironment=\"DATABASE_URL=postgres://postgres@localhost:5432/weron_communities?sslmode=disable\"\nEnvironment=\"REDIS_URL=redis://localhost:6379/1\"\nEnvironment=\"API_PASSWORD=myapipassword\"\n\n[Install]\nWantedBy=multi-user.target\nEOT\n\nsudo systemctl daemon-reload\n\nsudo systemctl restart weron-postgres\nsudo systemctl restart weron-redis\nsudo systemctl restart weron-signaler\n\nsudo firewall-cmd --permanent --add-port=1337/tcp\nsudo firewall-cmd --reload\n```\n\n\u003c/details\u003e\n\nIt should now be reachable on `ws://localhost:1337/`.\n\nTo use it in production, put this signaling server behind a TLS-enabled reverse proxy such as [Caddy](https://caddyserver.com/) or [Traefik](https://traefik.io/). You may also either want to keep `API_PASSWORD` empty to disable the management API completely or use OpenID Connect to authenticate instead; for more information, see the [signaling server reference](#signaling-server). You can also embed the signaling server in your own application using it's [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcsgl).\n\n### 2. Manage Communities with `weron manager`\n\nWhile it is possible to create ephemeral communities on a signaling server without any kind of authorization, you probably want to create a persistent community for most applications. Ephemeral communities get created and deleted automatically as clients join or leave, persistent communities will never get deleted automatically. You can manage these communities using the manager CLI.\n\nIf you want to work on your self-hosted signaling server, first set the remote address:\n\n```shell\n$ export WERON_RADDR='http://localhost:1337/'\n```\n\nNext, set the API password using the `API_PASSWORD` env variable:\n\n```shell\n$ export API_PASSWORD='myapipassword'\n```\n\nIf you use OIDC to authenticate, you can instead set the API password using [goit](https://github.com/pojntfx/goit) like so:\n\n```shell\n$ export OIDC_CLIENT_ID='Ab7OLrQibhXUzKHGWYDFieLa2KqZmFzb' OIDC_ISSUER='https://pojntfx.eu.auth0.com/' OIDC_REDIRECT_URL='http://localhost:11337'\n$ export API_KEY=\"$(goit)\"\n```\n\nIf we now list the communities, we see that none currently exist:\n\n```shell\n$ weron manager list\nid,clients,persistent\n```\n\nWe can create a persistent community using `weron create`:\n\n```shell\n$ weron manager create --community mycommunity --password mypassword\nid,clients,persistent\nmycommunity,0,true\n```\n\nIt is also possible to delete communities using `weron delete`, which will also disconnect all joined peers:\n\n```shell\n$ weron manager delete --community mycommunity\n```\n\nFor more information, see the [manager reference](#manager). You can also embed the manager in your own application using its [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcmgr).\n\n### 3. Test the System with `weron chat`\n\nIf you want to work on your self-hosted signaling server, first set the remote address:\n\n```shell\n$ export WERON_RADDR='ws://localhost:1337/'\n```\n\nThe chat is an easy way to test if everything is working correctly. To join a chatroom, run the following:\n\n```shell\n$ weron chat --community mycommunity --password mypassword --key mykey --names user1,user2,user3 --channels one,two,three\n```\n\nOn another peer, run the following (if your signaling server is public, you can run this anywhere on the planet):\n\n```shell\n$ weron chat --community mycommunity --password mypassword --key mykey --names user1,user2,user3 --channels one,two,three\n.wss://weron.up.railway.app/\nuser2!\n+user1@one\n+user1@two\n+user1@three\nuser2\u003e\n```\n\nYou can now start sending and receiving messages or add new peers to your chatroom to test the network.\n\nFor more information, see the [chat reference](#chat). You can also embed the chat in your own application using its [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcchat).\n\n### 4. Measure Latency with `weron utility latency`\n\nAn insightful metric of your network is its latency, which you can measure with this utility; think of this as `ping`, but for WebRTC. First, start the latency measurement server like so:\n\n```shell\n$ weron utility latency --community mycommunity --password mypassword --key mykey --server\n```\n\nOn another peer, launch the client, which should start measuring the latency immediately; press \u003ckbd\u003eCTRL\u003c/kbd\u003e \u003ckbd\u003eC\u003c/kbd\u003e to stop it and get the total statistics:\n\n```shell\n$ weron utility latency --community mycommunity --password mypassword --key mykey\n# ...\n128 B written and acknowledged in 110.111µs\n128 B written and acknowledged in 386.12µs\n128 B written and acknowledged in 310.458µs\n128 B written and acknowledged in 335.341µs\n128 B written and acknowledged in 264.149µs\n^CAverage latency: 281.235µs (5 packets written) Min: 110.111µs Max: 386.12µs\n```\n\nFor more information, see the [latency measurement utility reference](#latency-measurement-utility). You can also embed the utility in your own application using its [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcltc).\n\n### 5. Measure Throughput with `weron utility throughput`\n\nIf you want to transfer large amounts of data, your network's throughput is a key characteristic. This utility allows you to measure this metric between two nodes; think of it as `iperf`, but for WebRTC. First, start the throughput measurement server like so:\n\n```shell\n$ weron utility throughput --community mycommunity --password mypassword --key mykey --server\n```\n\nOn another peer, launch the client, which should start measuring the throughput immediately; press \u003ckbd\u003eCTRL\u003c/kbd\u003e \u003ckbd\u003eC\u003c/kbd\u003e to stop it and get the total statistics:\n\n```shell\n$ weron utility throughput --community mycommunity --password mypassword --key mykey\n# ...\n97.907 MB/s (783.253 Mb/s) (50 MB read in 510.690403ms)\n64.844 MB/s (518.755 Mb/s) (50 MB read in 771.076908ms)\n103.360 MB/s (826.881 Mb/s) (50 MB read in 483.745832ms)\n89.335 MB/s (714.678 Mb/s) (50 MB read in 559.692495ms)\n85.582 MB/s (684.657 Mb/s) (50 MB read in 584.233931ms)\n^CAverage throughput: 74.295 MB/s (594.359 Mb/s) (250 MB written in 3.364971672s) Min: 64.844 MB/s Max: 103.360 MB/s\n```\n\nFor more information, see the [throughput measurement utility reference](#throughput-measurement-utility). You can also embed the utility in your own application using it's [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcthr).\n\n### 6. Create a Layer 3 (IP) Overlay Network with `weron vpn ip`\n\nIf you want to join multiple nodes into an overlay network, the IP VPN is the best choice. It works similarly to i.e. Tailscale/WireGuard and can either dynamically allocate an IP address from a CIDR notation or statically assign one for you. On Windows, make sure to install [TAP-Windows](https://build.openvpn.net/downloads/releases/) first. Also note that due to technical limitations, only one IPv4 or IPv6 network and only one VPN instance at a time is supported on Windows; on macOS, only IPv6 networks are supported and IPv4 networks are ignored. To get started, launch the VPN on the first peer:\n\n```shell\n$ sudo weron vpn ip --community mycommunity --password mypassword --key mykey --ips 2001:db8::1/64,192.0.2.1/24\n{\"level\":\"info\",\"addr\":\"wss://weron.up.railway.app/\",\"time\":\"2022-05-06T22:20:51+02:00\",\"message\":\"Connecting to signaler\"}\n{\"level\":\"info\",\"id\":\"[\\\"2001:db8::6a/64\\\",\\\"192.0.2.107/24\\\"]\",\"time\":\"2022-05-06T22:20:56+02:00\",\"message\":\"Connected to signaler\"}\n```\n\nOn another peer, launch the VPN as well:\n\n```shell\n$ sudo weron vpn ip --community mycommunity --password mypassword --key mykey --ips 2001:db8::1/64,192.0.2.1/24\n{\"level\":\"info\",\"addr\":\"wss://weron.up.railway.app/\",\"time\":\"2022-05-06T22:22:30+02:00\",\"message\":\"Connecting to signaler\"}\n{\"level\":\"info\",\"id\":\"[\\\"2001:db8::b9/64\\\",\\\"192.0.2.186/24\\\"]\",\"time\":\"2022-05-06T22:22:36+02:00\",\"message\":\"Connected to signaler\"}\n{\"level\":\"info\",\"id\":\"[\\\"2001:db8::6a/64\\\",\\\"192.0.2.107/24\\\"]\",\"time\":\"2022-05-06T22:22:36+02:00\",\"message\":\"Connected to peer\"}\n```\n\nYou can now communicate between the peers:\n\n```shell\n$ ping 2001:db8::b9\nPING 2001:db8::b9(2001:db8::b9) 56 data bytes\n64 bytes from 2001:db8::b9: icmp_seq=1 ttl=64 time=1.07 ms\n64 bytes from 2001:db8::b9: icmp_seq=2 ttl=64 time=1.36 ms\n64 bytes from 2001:db8::b9: icmp_seq=3 ttl=64 time=1.20 ms\n64 bytes from 2001:db8::b9: icmp_seq=4 ttl=64 time=1.10 ms\n^C\n--- 2001:db8::b9 ping statistics ---\n4 packets transmitted, 4 received, 0% packet loss, time 3002ms\nrtt min/avg/max/mdev = 1.066/1.180/1.361/0.114 ms\n```\n\nIf you temporarily lose the network connection, the network topology changes etc. it will automatically reconnect. For more information and limitations on proprietary operating systems like macOS, see the [IP VPN reference](#layer-3-ip-overlay-networks). You can also embed the utility in your own application using its [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcip).\n\n### 7. Create a Layer 2 (Ethernet) Overlay Network with `weron vpn ethernet`\n\nIf you want more flexibility or work on non-IP networks, the Ethernet VPN is a good choice. It works similarly to `n2n` or ZeroTier. Due to API restrictions, this VPN type [is not available on macOS](https://support.apple.com/guide/deployment/system-and-kernel-extensions-in-macos-depa5fb8376f/web); use [Asahi Linux](https://asahilinux.org/), a computer that respects your freedoms or the layer 3 (IP) VPN instead. To get started, launch the VPN on the first peer:\n\n```shell\n$ sudo weron vpn ethernet --community mycommunity --password mypassword --key mykey\n{\"level\":\"info\",\"addr\":\"wss://weron.up.railway.app/\",\"time\":\"2022-05-06T22:42:10+02:00\",\"message\":\"Connecting to signaler\"}\n{\"level\":\"info\",\"id\":\"fe:60:a5:8b:81:36\",\"time\":\"2022-05-06T22:42:11+02:00\",\"message\":\"Connected to signaler\"}\n```\n\nIf you want to add an IP address to the TAP interface, do so with `iproute2` or your OS tools:\n\n```shell\n$ sudo ip addr add 192.0.2.1/24 dev tap0\n$ sudo ip addr add 2001:db8::1/32 dev tap0\n```\n\nOn another peer, launch the VPN as well:\n\n```shell\n$ sudo weron vpn ethernet --community mycommunity --password mypassword --key mykey\n{\"level\":\"info\",\"addr\":\"wss://weron.up.railway.app/\",\"time\":\"2022-05-06T22:52:56+02:00\",\"message\":\"Connecting to signaler\"}\n{\"level\":\"info\",\"id\":\"b2:ac:ae:b6:32:8c\",\"time\":\"2022-05-06T22:52:57+02:00\",\"message\":\"Connected to signaler\"}\n{\"level\":\"info\",\"id\":\"fe:60:a5:8b:81:36\",\"time\":\"2022-05-06T22:52:57+02:00\",\"message\":\"Connected to peer\"}\n```\n\nAnd add the IP addresses:\n\n```shell\n$ sudo ip addr add 192.0.2.2/24 dev tap0\n$ sudo ip addr add 2001:db8::2/32 dev tap0\n```\n\nYou can now communicate between the peers:\n\n```shell\n$ ping 2001:db8::2\nPING 2001:db8::2(2001:db8::2) 56 data bytes\n64 bytes from 2001:db8::2: icmp_seq=1 ttl=64 time=1.20 ms\n64 bytes from 2001:db8::2: icmp_seq=2 ttl=64 time=1.14 ms\n64 bytes from 2001:db8::2: icmp_seq=3 ttl=64 time=1.24 ms\n^C\n--- 2001:db8::2 ping statistics ---\n3 packets transmitted, 3 received, 0% packet loss, time 2002ms\nrtt min/avg/max/mdev = 1.136/1.193/1.239/0.042 ms\n```\n\nIf you temporarily lose the network connection, the network topology changes etc. it will automatically reconnect. You can also embed the utility in your own application using its [Go API](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtceth).\n\n### 8. Write your own protocol with `wrtcconn`\n\nIt is almost trivial to build your own distributed applications with weron, similarly to how [PeerJS](https://peerjs.com/) works. Here is the core logic behind a simple echo example:\n\n```go\n// ...\nfor {\n\tselect {\n\tcase id := \u003c-ids:\n\t\tlog.Println(\"Connected to signaler\", id)\n\tcase peer := \u003c-adapter.Accept():\n\t\tlog.Println(\"Connected to peer\", peer.PeerID, \"and channel\", peer.ChannelID)\n\n\t\tgo func() {\n\t\t\tdefer func() {\n\t\t\t\tlog.Println(\"Disconnected from peer\", peer.PeerID, \"and channel\", peer.ChannelID)\n\t\t\t}()\n\n\t\t\treader := bufio.NewScanner(peer.Conn)\n\t\t\tfor reader.Scan() {\n\t\t\t\tlog.Printf(\"%s\", reader.Bytes())\n\t\t\t}\n\t\t}()\n\n\t\tgo func() {\n\t\t\tfor {\n\t\t\t\tif _, err := peer.Conn.Write([]byte(\"Hello!\\n\")); err != nil {\n\t\t\t\t\treturn\n\t\t\t\t}\n\n\t\t\t\ttime.Sleep(time.Second)\n\t\t\t}\n\t\t}()\n\t}\n}\n```\n\nYou can either use the [minimal adapter](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcconn#Adapter) or the [named adapter](https://pkg.go.dev/github.com/pojntfx/weron/pkg/wrtcconn#NamedAdapter); the latter negotiates a username between the peers, while the former does not check for duplicates. For more information, check out the [Go API](https://pkg.go.dev/github.com/pojntfx/weron) and take a look at the provided [examples](./examples), utilities and services in the package for examples.\n\n🚀 **That's it!** We hope you enjoy using weron.\n\n## Reference\n\n### Library API\n\n- [![Go Reference](https://pkg.go.dev/badge/github.com/pojntfx/weron.svg)](https://pkg.go.dev/github.com/pojntfx/weron)\n\n### Command Line Arguments\n\n```shell\n$ weron --help\nOverlay networks based on WebRTC.\n\nFind more information at:\nhttps://github.com/pojntfx/weron\n\nUsage:\n  weron [command]\n\nAvailable Commands:\n  chat        Chat over the overlay network\n  completion  Generate the autocompletion script for the specified shell\n  help        Help about any command\n  manager     Manage a signaling server\n  signaler    Start a signaling server\n  utility     Utilities for overlay networks\n  vpn         Join virtual private networks built on overlay networks\n\nFlags:\n  -h, --help          help for weron\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n\nUse \"weron [command] --help\" for more information about a command.\n```\n\n\u003cdetails\u003e\n  \u003csummary\u003eExpand subcommand reference\u003c/summary\u003e\n\n#### Signaling Server\n\n```shell\n$ weron signaler --help\nStart a signaling server\n\nUsage:\n  weron signaler [flags]\n\nAliases:\n  signaler, sgl, s\n\nFlags:\n      --api-password string     Password for the management API (can also be set using the API_PASSWORD env variable). Ignored if any of the OIDC parameters are set.\n      --api-username string     Username for the management API (can also be set using the API_USERNAME env variable). Ignored if any of the OIDC parameters are set. (default \"admin\")\n      --cleanup                 (Warning: Only enable this after stopping all other servers accessing the database!) Remove all ephemeral communities from database and reset client counts before starting\n      --ephemeral-communities    Enable the creation of ephemeral communities (default true)\n      --heartbeat duration      Time to wait for heartbeats (default 10s)\n  -h, --help                    help for signaler\n      --laddr string            Listening address (can also be set using the PORT env variable) (default \":1337\")\n      --oidc-client-id string   OIDC Client ID (i.e. myoidcclientid) (can also be set using the OIDC_CLIENT_ID env variable)\n      --oidc-issuer string      OIDC Issuer (i.e. https://pojntfx.eu.auth0.com/) (can also be set using the OIDC_ISSUER env variable)\n      --postgres-url string     URL of PostgreSQL database to use (i.e. postgres://myuser:mypassword@myhost:myport/mydatabase) (can also be set using the DATABASE_URL env variable). If empty, a in-memory database will be used.\n      --redis-url string        URL of Redis database to use (i.e. redis://myuser:mypassword@myhost:myport/1) (can also be set using the REDIS_URL env variable). If empty, a in-process broker will be used.\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n#### Manager\n\n```shell\n$ weron manager --help\nManage a signaling server\n\nUsage:\n  weron manager [command]\n\nAliases:\n  manager, mgr, m\n\nAvailable Commands:\n  create      Create a persistent community\n  delete      Delete a persistent or ephemeral community\n  list        List persistent and ephemeral communities\n\nFlags:\n  -h, --help   help for manager\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n\nUse \"weron manager [command] --help\" for more information about a command.\n```\n\n#### Chat\n\n```shell\n$ weron chat --help\nChat over the overlay network\n\nUsage:\n  weron chat [flags]\n\nAliases:\n  chat, cht, c\n\nFlags:\n      --channels strings    Comma-separated list of channels in community to join (default [weron/chat/primary])\n      --community string    ID of community to join\n      --force-relay         Force usage of TURN servers\n  -h, --help                help for chat\n      --ice strings         Comma-separated list of STUN servers (in format stun:host:port) and TURN servers to use (in format username:credential@turn:host:port) (i.e. username:credential@turn:global.turn.twilio.com:3478?transport=tcp) (default [stun:stun.l.google.com:19302])\n      --id-channel string   Channel to use to negotiate names (default \"weron/chat/id\")\n      --key string          Encryption key for community\n      --kicks duration      Time to wait for kicks (default 5s)\n      --names strings       Comma-separated list of names to try and claim one from\n      --password string     Password for community\n      --raddr string        Remote address (default \"wss://weron.up.railway.app/\")\n      --timeout duration    Time to wait for connections (default 10s)\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n#### Latency Measurement Utility\n\n```shell\n$ weron utility latency --help\nMeasure the latency of the overlay network\n\nUsage:\n  weron utility latency [flags]\n\nAliases:\n  latency, ltc, l\n\nFlags:\n      --community string    ID of community to join\n      --force-relay         Force usage of TURN servers\n  -h, --help                help for latency\n      --ice strings         Comma-separated list of STUN servers (in format stun:host:port) and TURN servers to use (in format username:credential@turn:host:port) (i.e. username:credential@turn:global.turn.twilio.com:3478?transport=tcp) (default [stun:stun.l.google.com:19302])\n      --key string          Encryption key for community\n      --packet-length int   Size of packet to send and acknowledge (default 128)\n      --password string     Password for community\n      --pause duration      Time to wait before sending next packet (default 1s)\n      --raddr string        Remote address (default \"wss://weron.up.railway.app/\")\n      --server              Act as a server\n      --timeout duration    Time to wait for connections (default 10s)\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n#### Throughput Measurement Utility\n\n```shell\n$ weron utility throughput --help\nMeasure the throughput of the overlay network\n\nUsage:\n  weron utility throughput [flags]\n\nAliases:\n  throughput, thr, t\n\nFlags:\n      --community string    ID of community to join\n      --force-relay         Force usage of TURN servers\n  -h, --help                help for throughput\n      --ice strings         Comma-separated list of STUN servers (in format stun:host:port) and TURN servers to use (in format username:credential@turn:host:port) (i.e. username:credential@turn:global.turn.twilio.com:3478?transport=tcp) (default [stun:stun.l.google.com:19302])\n      --key string          Encryption key for community\n      --packet-count int    Amount of packets to send before waiting for acknowledgement (default 1000)\n      --packet-length int   Size of packet to send (default 50000)\n      --password string     Password for community\n      --raddr string        Remote address (default \"wss://weron.up.railway.app/\")\n      --server              Act as a server\n      --timeout duration    Time to wait for connections (default 10s)\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n#### Layer 3 (IP) Overlay Networks\n\n```shell\n$ weron vpn ip --help\nJoin a layer 3 overlay network\n\nUsage:\n  weron vpn ip [flags]\n\nAliases:\n  ip, i\n\nFlags:\n      --community string    ID of community to join\n      --dev string          Name to give to the TUN device (i.e. weron0) (default is auto-generated; only supported on Linux)\n      --force-relay         Force usage of TURN servers\n  -h, --help                help for ip\n      --ice strings         Comma-separated list of STUN servers (in format stun:host:port) and TURN servers to use (in format username:credential@turn:host:port) (i.e. username:credential@turn:global.turn.twilio.com:3478?transport=tcp) (default [stun:stun.l.google.com:19302])\n      --id-channel string   Channel to use to negotiate names (default \"weron/ip/id\")\n      --ips strings         Comma-separated list of IP networks to claim an IP address from and and give to the TUN device (i.e. 2001:db8::1/32,192.0.2.1/24) (on Windows, only one IP network (either IPv4 or IPv6) is supported; on macOS, IPv4 networks are ignored)\n      --key string          Encryption key for community\n      --kicks duration      Time to wait for kicks (default 5s)\n      --max-retries int     Maximum amount of times to try and claim an IP address (default 200)\n      --parallel int        Amount of threads to use to decode frames (default 20)\n      --password string     Password for community\n      --raddr string        Remote address (default \"wss://weron.up.railway.app/\")\n      --static              Try to claim the exact IPs specified in the --ips flag statically instead of selecting a random one from the specified network\n      --timeout duration    Time to wait for connections (default 10s)\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n#### Layer 2 (Ethernet) Overlay Networks\n\n```shell\n$ weron vpn ethernet --help\nJoin a layer 2 overlay network\n\nUsage:\n  weron vpn ethernet [flags]\n\nAliases:\n  ethernet, eth, e\n\nFlags:\n      --community string   ID of community to join\n      --dev string         Name to give to the TAP device (i.e. weron0) (default is auto-generated; only supported on Linux and macOS)\n      --force-relay        Force usage of TURN servers\n  -h, --help               help for ethernet\n      --ice strings        Comma-separated list of STUN servers (in format stun:host:port) and TURN servers to use (in format username:credential@turn:host:port) (i.e. username:credential@turn:global.turn.twilio.com:3478?transport=tcp) (default [stun:stun.l.google.com:19302])\n      --key string         Encryption key for community\n      --mac string         MAC address to give to the TAP device (i.e. 3a:f8:de:7b:ef:52) (default is auto-generated; only supported on Linux)\n      --parallel int       Amount of threads to use to decode frames (default 20)\n      --password string    Password for community\n      --raddr string       Remote address (default \"wss://weron.up.railway.app/\")\n      --timeout duration   Time to wait for connections (default 10s)\n\nGlobal Flags:\n  -v, --verbose int   Verbosity level (0 is disabled, default is info, 7 is trace) (default 5)\n```\n\n\u003c/details\u003e\n\n### Environment Variables\n\nAll command line arguments described above can also be set using environment variables; for example, to set `--max-retries` to `300` with an environment variable, use `WERON_MAX_RETRIES=300`.\n\n## Acknowledgements\n\n- [Font Awesome](https://fontawesome.com/) provides the assets used for the icon and logo.\n- [songgao/water](https://github.com/songgao/water) provides the TUN/TAP device library for weron.\n- [pion/webrtc](https://github.com/pion/webrtc) provides the WebRTC functionality.\n\n## Contributing\n\nTo contribute, please use the [GitHub flow](https://guides.github.com/introduction/flow/) and follow our [Code of Conduct](./CODE_OF_CONDUCT.md).\n\nTo build and start a development version of weron locally, run the following:\n\n```shell\n$ git clone https://github.com/pojntfx/weron.git\n$ cd weron\n$ make depend\n$ make \u0026\u0026 sudo make install\n$ weron signaler # Starts the signaling server\n# In another terminal\n$ weron chat --raddr ws://localhost:1337 --community mycommunity --password mypassword --key mykey --names user1,user2,user3 --channels one,two,three\n# In another terminal\n$ weron chat --raddr ws://localhost:1337 --community mycommunity --password mypassword --key mykey --names user1,user2,user3 --channels one,two,three\n```\n\nHave any questions or need help? Chat with us [on Matrix](https://matrix.to/#/#weron:matrix.org?via=matrix.org)!\n\n## License\n\nweron (c) 2025 Felicitas Pojtinger and contributors\n\nSPDX-License-Identifier: AGPL-3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpojntfx%2Fweron","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpojntfx%2Fweron","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpojntfx%2Fweron/lists"}