From a16a4b302c6525a13acbb4c22571a19c2a62a905 Mon Sep 17 00:00:00 2001
From: Klemens Nanni <kn@openbsd.org>
Date: Sat, 11 Oct 2025 03:09:20 +0300
Subject: [PATCH] Ensure :: in -http argument ends up as IPv6 socket

Do a first pass on the argument's host port alone to derive the address
family in this specific case before leaving it up to Golang.

The empty addresses `0.0.0.0` and `::` are resolved differently depending
on the OS.  At least on OpenBSD, which does not support dual-family sockets
like Linux, net.Dial() turns both into an IPv4 wildcard socket unless the
"tcp6" network (Golang terminology) is requested.

Therefore, such systems are unable to have dms listen on all IPv6 addresses.

Imho, this should be fixed in Golang proper, but that's a whole different
story;  until then, this is enough to make dms work in my IPv6-only network
as tested with an Android-based appliance using VLC:
```
$ fstat -p $(pgrep dms) | grep internet
_dms     dms        91669    3* internet6 stream tcp 0x0 *:1338
_dms     dms        91669    7* internet6 dgram udp *:1900
_dms     dms        91669    8* internet6 dgram udp *:1900
```

To illustrate the problem:
```
$ go version
go version go1.25.1 openbsd/amd64
$ cat listener.go
package main
import (
	"fmt"
	"net"
)
func main() {
	nets  := []string{"tcp", "tcp4", "tcp6"}
	addrs := []string{"", "0.0.0.0", "127.0.0.1", "[::]", "[::1]"}
	for _, n := range nets {
		for _, a := range addrs {
			fmt.Printf("%4s %7s => ", n, a)
			l, err := net.Listen(n, a + ":1338")
			if  err != nil {
				fmt.Println(err)
			} else {
				fmt.Printf("%14s\n", l.Addr())
				l.Close()
			}
		}
	}
}
$ go run listener.go
 tcp           =>   0.0.0.0:1338
 tcp   0.0.0.0 =>   0.0.0.0:1338
 tcp 127.0.0.1 => 127.0.0.1:1338
 tcp      [::] =>   0.0.0.0:1338
 tcp     [::1] =>     [::1]:1338
tcp4           =>   0.0.0.0:1338
tcp4   0.0.0.0 =>   0.0.0.0:1338
tcp4 127.0.0.1 => 127.0.0.1:1338
tcp4      [::] =>   0.0.0.0:1338
tcp4     [::1] => listen tcp4: address ::1: no suitable address found
tcp6           =>      [::]:1338
tcp6   0.0.0.0 => listen tcp6: address 0.0.0.0: no suitable address found
tcp6 127.0.0.1 => listen tcp6: address 127.0.0.1: no suitable address found
tcp6      [::] =>      [::]:1338
tcp6     [::1] =>     [::1]:1338
```
---
 main.go | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)

diff --git a/main.go b/main.go
index 8dd8641..68530c0 100644
--- a/main.go
+++ b/main.go
@@ -222,7 +222,15 @@ func mainErr() error {
 			return
 		}(config.IfName),
 		HTTPConn: func() net.Listener {
-			conn, err := net.Listen("tcp", config.Http)
+			network := "tcp"
+			host, _, err := net.SplitHostPort(config.Http)
+			if err != nil {
+				log.Fatal(err)
+			}
+			if host == "::" {
+				network = "tcp6"
+			}
+			conn, err := net.Listen(network, config.Http)
 			if err != nil {
 				log.Fatal(err)
 			}
