From mboxrd@z Thu Jan 1 00:00:00 1970 Authentication-Results: mail.toke.dk; spf=pass smtp.mailfrom=orleans.occnc.com; dkim=pass header.d=orleans.occnc.com; arc=none (Message is not ARC signed); dmarc=none Received: from mta6-tap0.andover.occnc.com (mta6-tap0.andover.occnc.com [IPv6:2600:2c00:b000:2500::153]) by mail.toke.dk (Postfix) with ESMTPS id 5752AE7997F for ; Sun, 22 Mar 2026 01:40:13 +0100 (CET) Received: from harbor6.andover.occnc.com (harbor6.andover.occnc.com [IPv6:2600:2c00:b000:2500::610b]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519MLKEM768 server-signature ECDSA (secp384r1) server-digest SHA384) (Client did not present a certificate) (Authenticated sender: curtis@occnc.com) by mta6-tap0.andover.occnc.com (Postfix) with ESMTPSA id 16E06F23F; Sat, 21 Mar 2026 20:40:10 -0400 (EDT) DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=orleans.occnc.com; s=curtis-orleans-20250605-224653; t=1774140010; bh=9HPg/A2j+CV6B/rALb/2RJAk6g497UWgM4DaINk1GUw=; h=To:cc:Reply-To:From:Subject:In-reply-to:Date; b=rcK4uazPul/hZeaz988mRbaVsmv7SjDOIpUiO1XygkCOOdD/RwvzGW11ud4XnvQ6m k6q+E/2zlVZa01E6DdqHI7CdhO6Ziu5L5JaseaM6BB0SUjUis0JG4oINXw0K2OsHS2 CB0FwFP7ZWZ/fDgF7n/pX2u4FrZmXNWPX1C6beSq0kGigYv2oXtJWBLyI3Egoh2bnr L5T1EChSqhiIDHWgcxVG2Qq/pIAuXIL4l6XyELGVlkiv2+yeVnmWybt0Yr1AGlKySm NnMOzmgkkq3OiScspeYziTN3b5PFhhyH1Guyuv8cR+YuQDmN02q4/54IeWlcrwDQka 6iswP2NOnMStA== To: Curtis Villamizar cc: Juliusz Chroboczek , galene@lists.galene.org From: Curtis Villamizar In-reply-to: Your message of "Fri, 20 Mar 2026 12:03:51 -0400." MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-ID: <93457.1774139592.1@harbor6.andover.occnc.com> Date: Sat, 21 Mar 2026 20:33:12 -0400 Message-ID: <177414001575.1734.11139909826447213275@gauss> Message-ID-Hash: LNMUM6XAELYDGUHQLQDHWNDWWI2B5CN3 X-Message-ID-Hash: LNMUM6XAELYDGUHQLQDHWNDWWI2B5CN3 X-MailFrom: curtis@orleans.occnc.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header X-Mailman-Version: 3.3.10 Precedence: list Reply-To: Curtis Villamizar Subject: [Galene] Re: galene on IPv6 only List-Id: =?utf-8?q?Gal=C3=A8ne_videoconferencing_server_discussion_list?= Archived-At: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: replying to myself ... In message Curtis Villamizar writes: > > In message <874imask25.wl-jch@irif.fr> > Juliusz Chroboczek writes: > > > Hello, > > > > > It looks like galene does not want to work on an IPv6 only server. > > > > Thanks a lot for your testing, that's the kind of deployment that we > > should be supporting. > > > > > I also get messages related to IPv4-ish stuff. > > > Failed to enable mDNS over IPv4: > > > (listen udp4 224.0.0.0:5353: socket: protocol not supported) > > > > > > mDNS is disabled by default for a very long time. See galene.go line 49: > > > > flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses") > > > > I think the issue here is that UseMDNS is not obeyed by the relay test. > > I'll fix that ASAP. > > Thanks. Very responsive on your part. It seems mDNS is attempted for some reason if relay test fails. Otherwise no issue. > > > Relay test failed: timeout 2026/03/19 07:41:38 > > > Perhaps you didn't configure a TURN server? > > > TURN: no public addresses > > > > > > The second message is benign and only indicates the relayTest() test > > > has failed even though it should not be run if there is no IPv4. > > > > RelayTest is run unconditionally, since it should be successful with an > > IPv6 TURN server. The issue here is that the built-in TURN server does > > not implement RFC 6156, you need to use Coturn or some other full-featured > > TURN server. Understood after your later reply on this. btw- works fine with builtin server and no IPv6 NAT in the way. > There needs to be an ability to disable the loopback test. I have no > need for a TURN server and I think this will be common among those > running IPv6 only. Still would be nice but since I may be the only one asking for this I'll look into whether it is feasible. > > We should probably run two relay tests, one over IPv4 and one over IPv6. > > > > > This is IPv6 so no need for ICE, STUN, TURN, etc. > > > > I, too, used to be optimistic about IPv6 ;-) > > That is another discussion. So I'll try to be brief. [ ... trim ... opinions on IPv6 omitted ... ] > > ICE is still required, since both address selection and blackhole > > detection are done by ICE. STUN and TURN are useful if there's a firewall > > in the way, which sadly is often the case, even with IPv6. > > This is not a problem in my case. IPv6 in the clear, no NAT. Maybe you can convince me on the blackhole detection. > > > There is nothing on the local lan (its in a datacenter) so no need for > > > mDNS and running mDNS is *very* bad form in that type of environment. > > > > Yes, mDNS is disabled by default. I need more information to understand > > why it's not being disabled in your case. > > With the admitedly kludgy patch the problem is gone so maybe it was > the relay test which I now disabled. That saying, I didn't look at > the code much. Now conditionally disabled in latest patch. > > > If instead of using the IPv6 address inside [] I use the host name, then > > > not solved. Even though the host has an AAAA DNS record and no > > > A record, the bind does not work if the host name is specified. This > > > may be an upstream problem in the go net library. > > > > Interesting. I'll see if I can reproduce it. > > That's with my kludgy patch. Maybe standby and I'll put together a > more robust patch. Somewhat less kludgy patch provided for your entertainment and feedback. > Up and sort of running but I still need some work. This would have > gone a lot faster if there were better documentation and better > diagnostics on json issues. I have to say that initial setup was > somewhat painful. I'll let you if there are any further problems that > are not unique to my misconfiguration. I'll try to help rather than > just whine. > > > -- Juliusz > > _______________________________________________ > > Galene mailing list -- galene@lists.galene.org > > To unsubscribe send an email to galene-leave@lists.galene.org Seems the problem is some go functions in the standard library want tcp6 rather than TCP when running on FreeBSD (and probably *BSD but not confirmed). Some short(ish) patches are attached. You may not want to take the disable-turn patches (or any at this point). Comments welcome and encouraged. Main change is verbosely named GetTCPProtoOfAddrString function that takes the address string and returns a protocol name of tcp4 for IPv4 only, tcp6 for IPv6 only, and tcp for dual stack (which won't work for the IPv6 port), and tcp for unknown (ie: :8443 with no addr). This approach needs improvement but this is the less kludgy 2nd iteration. I think what should happen for FreeBSD is two or more listens in the dual stack case with the port only format looking at all interface addresses and creating a listen for each one. This patch works for the IPv6 only case. Using -disable-relay-test suppresses the relay test and therefore nMDS getting tried and the relay test failed complaint in the log. I still get "TURN: no public addresses" in the log but everything works. With -disable-turn I don't get video or audio. I should be able to "borrow" a global routable IPv4 address for the purpose of testing dual stack, even though they are in short supply. Curtis --- galene.go.orig 2025-08-09 10:26:35.000000000 -0400 +++ galene.go 2026-03-21 17:29:18.061013000 -0400 @@ -26,6 +26,7 @@ func main() { var cpuprofile, memprofile, mutexprofile, httpAddr string var udpRange string + var disableturn, disablerelaytest bool flag.StringVar(&httpAddr, "http", ":8443", "web server `address`") flag.StringVar(&webserver.StaticRoot, "static", "./static/", @@ -47,12 +48,22 @@ flag.StringVar(&udpRange, "udp-range", "", "UDP `port` (multiplexing) or port1-port2 (range)") flag.BoolVar(&group.UseMDNS, "mdns", false, "gather mDNS addresses") + flag.BoolVar(&disablerelaytest, "disable-relay-test", false, + "disable the relay test") + flag.BoolVar(&disableturn, "disable-turn", false, + "disable TURN (if true overrides -turn)") flag.BoolVar(&ice.ICERelayOnly, "relay-only", false, "require use of TURN relays for all media traffic") flag.StringVar(&turnserver.Address, "turn", "auto", "built-in TURN server `address` (\"\" to disable)") flag.Parse() + log.Printf("starting: httpAddr = %s", httpAddr) + + if (disableturn) { + turnserver.Address = "" + } + if udpRange != "" { if strings.ContainsRune(udpRange, '-') { var min, max uint16 @@ -145,7 +156,9 @@ terminate := make(chan os.Signal, 1) signal.Notify(terminate, syscall.SIGINT, syscall.SIGTERM) - go relayTest() + if ! disablerelaytest { + go relayTest() + } ticker := time.NewTicker(15 * time.Minute) defer ticker.Stop() --- webserver/webserver.go.orig 2025-08-09 10:26:35.000000000 -0400 +++ webserver/webserver.go 2026-03-21 11:35:42.778748000 -0400 @@ -32,6 +32,55 @@ var StaticRoot string var Insecure bool + +// GetTCPProtoOfAddrString +// returns tcp4 if using IPv4 only +// returns tcp6 if using IPv6 only +// returns tcp if dual stack or unspecified (ie: address form ":port") + +func GetTCPProtoOfAddrString(address string) (string, error) { + host, port, err := net.SplitHostPort(address) + _ = port + if (err != nil) { + log.Printf("SplitHostPort: %s got error %s\n", + address, err.Error()) + return "tcp", err; + } + if (len(host) == 0) { + return "tcp", nil // no host part of address + } + var addrs []string + addrs, err = net.LookupHost(host) + if (err != nil) { + log.Printf("LookupHost: %s got error %s\n", + host, err.Error()) + return "tcp", err; + } + var addr, proto string + proto = "any" + for i := 0; i < len(addrs); i++ { + addr = addrs[i] + if (strings.ContainsAny(addr, ":")) { + if (proto == "any") { + proto = "tcp6" + } else if (proto == "tcp4") { + proto = "tcp" + break + } + } else { + if (proto == "any") { + proto = "tcp4" + } else if (proto == "tcp6") { + proto = "tcp" + break + } + } + } + if (proto == "any") { + proto = "tcp" + } + return proto, nil +} func Serve(address string, dataDir string) error { http.Handle("/", &fileHandler{http.Dir(StaticRoot)}) @@ -69,12 +118,19 @@ server = s - proto := "tcp" + var proto string + var err error if strings.HasPrefix(address, "/") { proto = "unix" + } else { + proto, err = GetTCPProtoOfAddrString(address) + if (err != nil) { + return err + } } - listener, err := net.Listen(proto, address) + var listener net.Listener + listener, err = net.Listen(proto, address) if err != nil { return err } @@ -553,7 +609,13 @@ } var addr net.Addr - tcpaddr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr) + proto, err := GetTCPProtoOfAddrString(r.RemoteAddr) + if (err != nil) { + log.Printf("ResolveTCPAddr: addr= %s, error= %s", + r.RemoteAddr, err.Error()) + proto = "tcp" + } + tcpaddr, err := net.ResolveTCPAddr(proto, r.RemoteAddr) if err != nil { log.Printf("ResolveTCPAddr: %v", err) } else { --- webserver/whip.go.orig 2025-08-09 10:26:35.000000000 -0400 +++ webserver/whip.go 2026-03-21 10:23:48.856329000 -0400 @@ -212,7 +212,15 @@ } var addr net.Addr - tcpaddr, err := net.ResolveTCPAddr("tcp", r.RemoteAddr) + proto, err := GetTCPProtoOfAddrString(r.RemoteAddr) + if (err != nil) { + log.Printf("ResolveTCPAddr: addr= %s, error= %s", + r.RemoteAddr, err.Error()) + proto = "tcp" + } + log.Printf("ResolveTCPAddr: addr= %s, proto= %s", + r.RemoteAddr, proto) + tcpaddr, err := net.ResolveTCPAddr(proto, r.RemoteAddr) if err != nil { log.Printf("ResolveTCPAddr: %v", err) } else {