Skip to content

poeggi/bds-ipv6fix

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

20 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

bds-ipv6fix

LD_PRELOAD shim for Minecraft Bedrock Dedicated Server that fixes a known BDS limitation where IPv4 and IPv6 cannot be configured on the same port.

When the fix is active and working, you will see a line like this in your server log:

[bds-ipv6fix] Fixing IPv6: IPV6_V6ONLY=1 set on fd=... port=...

The shim is safe to leave in place across BDS upgrades. If a future BDS version fixes this issue on its own, the shim detects it automatically and logs a NOTE: ... patch is now redundant message — it will not interfere with the server.

See the full technical description in bds-ipv6fix.c.

Usage

Consumed by itzg/docker-minecraft-bedrock-server via ENABLE_BDS_V6BIND_FIX=true. Pre-built binaries for x86_64 and aarch64 are available on the releases page.

The itzg image sets LD_PRELOAD to the shim when ENABLE_BDS_V6BIND_FIX=true is set.

To use the shim outside of the itzg image:

curl -fsSL "https://github.com/poeggi/bds-ipv6fix/releases/latest/download/bds-ipv6fix_linux_$(uname -m).so" \
  -o bds-ipv6fix.so
export LD_PRELOAD=$(pwd)/bds-ipv6fix.so
exec ./bedrock_server

Building

# amd64
gcc -shared -fPIC -O2 -o bds-ipv6fix_linux_x86_64.so bds-ipv6fix.c -ldl

# aarch64 (cross-compile)
aarch64-linux-gnu-gcc -shared -fPIC -O2 -o bds-ipv6fix_linux_aarch64.so bds-ipv6fix.c -ldl

Dear Mojang/Microsoft

This shim exists because bedrock_server binds its IPv6 socket without first calling setsockopt(IPV6_V6ONLY, 1). The socket therefore inherits the host kernel's net.ipv6.bindv6only default (0 on most Linux systems), which means the IPv6 socket absorbs IPv4-mapped traffic as well. When a user sets SERVER_PORT and SERVER_PORT_V6 to the same value, the subsequent IPv4 bind fails with EADDRINUSE and BDS segfaults.

The native fix is a one-liner between socket() and bind() in the IPv6 socket setup path:

int one = 1;
setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &one, sizeof(one));

This makes the IPv6 socket strictly IPv6-only, allows both address families to share a port, and makes this shim unnecessary. The Bedrock client does not implement Happy Eyeballs (RFC 8305), so players whose DNS e.g. returns IPv6 first will silently time out if the client was configured to connect to the port only valid for IPv4 (and vice-versa) -> same-port dual-stack is the best we can do to fix this on the server side.

Additional Happy Eyeballs on client side still considered beneficial, as it would mitigate all other dual-stack issues in the network path between client and server.

License

MIT

Authors

poeggi with Claude (Anthropic)

About

Bedrock Dedicated Server IPv6 runtime fix, allowing IPv6 and IPv4 to bind to same port number (help mitigate bedrock client's missing Happy Eyeballs) - co-authored with Claude Code AI

Resources

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages