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
# 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)
}