## Summary
- ipv6rwc: validate IPv6 packet length before reading the version nibble
in writePC
- config: guard the BOM check against configs shorter than two bytes
- admin: replace unchecked net.Error type assertion with errors.As;
tolerate empty unix socket paths
- multicast: log and continue on ReadFrom errors instead of panicking;
use checked type assertion on UDPAddr
- mobile: reject negative length in SendBuffer; nil-check AddrForKey in
GetPeersJSON and SummaryForConfig
- admin/get{tree,paths,sessions}: skip entries when AddrForKey returns
nil instead of dereferencing
- core/nodeinfo: validate the requested public key length in
nodeInfoAdminHandler, matching the other proto handlers
- add regression tests for the panic paths
## Why
A handful of error paths and platform-API edge cases reach fixed-size
indexing or unchecked type assertions before any length validation.
Most are reachable only locally (an empty config piped to -useconf,
a 0-byte packet from the mobile bindings, an admin DialTimeout error
that doesn't satisfy net.Error on some platforms), but they crash the
daemon hard. Have them return errors or skip the entry instead.
## Testing
- go test ./...
- go vet ./...
Adds an `origin` query option for `ws://` listener URLs so peer
operators can
explicitly allow browser-hosted WebSocket clients.
- `ws://host:port` keeps the existing same-origin behavior
- `ws://host:port?origin=demo.example.org` allows that origin host
- `ws://host:port?origin=https://demo.example.org` allows that scheme
and host
- repeated `origin=` parameters allow multiple origin patterns
- `origin=*` intentionally disables origin verification for public
WebSocket
peer endpoints
## Problem
I've implemented a WASM based browser demo yggdrasil node to found that
it
cannot directly dial any existing public `ws://` or `wss://` peers.
Browsers always include an `Origin` header in WebSocket handshakes, and
the
JavaScript `WebSocket()` constructor does not allow applications to
override or
remove arbitrary handshake headers.
This means a browser demo served from an origin such as
`http://127.0.0.1:8000` cannot connect to a public peer whose WebSocket
server
only accepts same-origin handshakes.
Write a newline to the specified file-descriptor to signal that
yggdrasil is fully initialised and ready.
s6 service startup notifications are described
[here](https://skarnet.org/software/s6/notifywhenup.html).
Related: #1148
## Summary
- validate handshake metadata field lengths before fixed-size reads
- reject truncated multicast advertisements before slicing the hash
payload
- add regression tests for malformed and truncated input
## Why
Both parsers currently trust length information from the incoming
payload a bit too much. Malformed network input can reach fixed-size
reads/slices and panic the process instead of being rejected cleanly.
## Testing
- go test ./...
Currently, all init scripts, except for systemd, will generate a config
file with default permissions, which is usually `rw-r--r--`.
This is bad, because the config contains a private key.
The systemd service does `chmod 640` after creating the config, which is
much better than just leaving it readable for everyone forever, but
there is still a slight chance that some malicious program might steal
the private key during the time window between key creation and chmod.
For this reason, in this pull request I use `umask 037`, so the config
won't have read permission for others in the first place.
Note that I have only tested openrc and systemd services.
Also, I'm not sure what to do with the contrib/msi/build-msi.sh script,
which creates a bat file that generates a config. I don't know anything
about file permissions on windows, however, it seems that the bat file
generates the config into a user's personal directory, so maybe it's
already somewhat fine.
# Summary
This PR addresses failures to run Yggdrasil on ARM systems. The root
cause was the lack of ARM artifacts/images, which led to exec format
error and similar issues.
## What’s added:
- ```Dockerfile.multiarch``` — multi-stage Go build that correctly
propagates GOOS/GOARCH for linux/amd64, linux/arm64, linux/armhf and
linux/armel platform.
- ```entrypoint.sh``` - Introduced ENV **ALLOW_IPV6_FORWARDING**. When
set to a truthy value (e.g., true), the entrypoint executes: ```sysctl
-w net.ipv6.conf.all.forwarding=1```.
- GitHub Action for multi-arch builds and publishing to GHCR — triggered
via ```workflow_dispatch```, push to ```master``` and release via tags
(with docker semantic tags e.g. v0.5.12 → 0.5.12, 0.5, 0).
Example published images:
[https://github.com/Forne/yggdrasil-go/pkgs/container/yggdrasil-go](https://github.com/Forne/yggdrasil-go/pkgs/container/yggdrasil-go)
## Testing
✅ Ubuntu (24.04, amd64) — image runs correctly.
✅ macOS (Apple Silicon, arm64) — image runs correctly.
✅ MikroTik RouterOS (arm64) — image runs under the RouterOS container
package.
sys/kern/kern_pledge.c r1.329[0] removed the unveil bypass for "dns",
so "rpath" is needed for Go's DNS to stat(2) it.
Since current "/ rwc" and "cpath" with the new "rpath" amount to full
read access, there is no point in unveiling anymore.
0:
8d49ad01ac