Hi, Unfortunately, the only way to avoid having two sockets in this scenario, is to listen to only one of 127.0.0.1 or ::1 and live with that it's only one address family. As you might've noticed, some tools still struggle with connecting to ::1 so listening to 127.0.0.1 is the most safe option. Most client will try to connect to both ::1 and 127.0.0.1 when given localhost as target. In the case of browsers, they usually do it in parallel and use the quickest succeeding connection (this is called Happy Eyeballs if you wish to Google it).
The reason it works this way is that you bind the socket to an address, either ::1 or 127.0.0.1. There's no address that binds to multiple address families, except for :: that listen on all interfaces. Regards, Per Johansson On Wednesday, January 10, 2024 at 9:54:12 PM UTC+1 Tony M wrote: > How do I listen on all* local / loopback* ipv4 /ipv6 interfaces? > net.Listen('tcp', ':9999') listens on all interfaces. For my application > (oauth token listener) I only want to listen to local / loopback > > go doc Net.listen: > > > * if the host in the address parameter is empty or a literal > unspecified IP address, Listen listens on all available unicast and > anycast IP addresses of the local system.* > > My current workarounds are not ideal : > * implement MultiListener interface with 2 listeners\ > * Listen on 2 net.Listen listeners with 2 http.Serve servers > > > Example test with netstat showing the issue. > SEE EXAMPLE CODE BELOW > > # Listen :9999 > $ go run . -i all & > $ netstat -tulnp |grep v2 > tcp6 0 0 :::9999 :::* LISTEN > 28107/v2 > > # listen [127.0.0.1]:9999 > $ go run . -i ipv4 & > $ netstat -tulnp |grep v2 > tcp 0 0 127.0.0.1:9999 0.0.0.0:* > LISTEN 29244/v2 > > # listen [::1]:9999 > $ go run . -i ipv6 > $ netstat -tulnp |grep v2 > tcp6 0 0 ::1:9999 :::* LISTEN > 30163/v2 > > Telnet v4 does not work with v6 listen: > $ go run . -i ipv6 > $ telnet 127.0.0.1 9999 > Trying 127.0.0.1... > telnet: Unable to connect to remote host: Connection refused > > > Example Code > > package main > > import ( > "flag" > "fmt" > "net" > "time" > ) > > func main() { > optListen := flag.String("i", "all", "all / ipv6, ipv4") > > addrMap := map[string]string{ > "all": ":9999", > "ipv6": "[::1]:9999", > "ipv4": "[127.0.0.1]:9999", > } > > flag.Parse() > > fmt.Printf("Listen: %s\n", *optListen) > addr, ok := addrMap[*optListen] > if !ok { > panic("not found") > } > if l1, err := net.Listen("tcp", addr); err == nil { > fmt.Printf("l1: %s\n", l1.Addr().String()) > } else { > panic(err) > } > > time.Sleep(30 * time.Second) > } > > > -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/58047b81-c9b1-46ac-92e8-aca1396e13b9n%40googlegroups.com.