Galène videoconferencing server discussion list archives
 help / color / mirror / Atom feed
From: Curtis Villamizar <curtis@orleans.occnc.com>
To: Curtis Villamizar <curtis@orleans.occnc.com>
Cc: Juliusz Chroboczek <jch@irif.fr>, galene@lists.galene.org
Subject: [Galene] Re: galene on IPv6 only
Date: Sat, 21 Mar 2026 20:33:12 -0400	[thread overview]
Message-ID: <177414001575.1734.11139909826447213275@gauss> (raw)
In-Reply-To: Your message of "Fri, 20 Mar 2026 12:03:51 -0400." <cmu-lmtpd-35891-1774022493-0@mda62.andover.occnc.com>

replying to myself ...

In message <cmu-lmtpd-35891-1774022493-0@mda62.andover.occnc.com>
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 {

       reply	other threads:[~2026-03-22  0:40 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cmu-lmtpd-35891-1774022493-0@mda62.andover.occnc.com>
2026-03-22  0:33 ` Curtis Villamizar [this message]
2026-03-20  3:50 [Galene] galene on IPv6 only Curtis Villamizar
2026-03-20 13:32 ` [Galene] " Juliusz Chroboczek
2026-03-20 16:03   ` Curtis Villamizar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://lists.galene.org/postorius/lists/galene.lists.galene.org/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=177414001575.1734.11139909826447213275@gauss \
    --to=curtis@orleans.occnc.com \
    --cc=galene@lists.galene.org \
    --cc=jch@irif.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox