123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566 |
- // Package util provides various useful functions for completing the
- // "Whispering Gophers" code lab.
- package util
- import (
- "crypto/rand"
- "errors"
- "fmt"
- "net"
- )
- // ListenOnFirstUsableInterface returns a Listener that listens on the first
- // available port on the first available non-loopback IPv4 network interface.
- // It may not be the one you want (192.168.nn.128 won't usually be reachable from
- // outside your machine).
- func ListenOnFirstUsableInterface() (net.Listener, error) {
- ip, err := firstExternalIP()
- if err != nil {
- return nil, fmt.Errorf("could not find active non-loopback address: %v", err)
- }
- return net.Listen("tcp4", ip+":0")
- }
- func firstExternalIP() (string, error) {
- ifaces, err := net.Interfaces()
- if err != nil {
- return "", err
- }
- for _, iface := range ifaces {
- if iface.Flags&net.FlagUp == 0 {
- continue // interface down
- }
- if iface.Flags&net.FlagLoopback != 0 {
- continue // loopback interface
- }
- addrs, err := iface.Addrs()
- if err != nil {
- return "", err
- }
- for _, addr := range addrs {
- var ip net.IP
- switch v := addr.(type) {
- case *net.IPNet:
- ip = v.IP
- case *net.IPAddr:
- ip = v.IP
- }
- if ip == nil || ip.IsLoopback() {
- continue
- }
- ip = ip.To4()
- if ip == nil {
- continue // not an ipv4 address
- }
- return ip.String(), nil
- }
- }
- return "", errors.New("are you connected to the network?")
- }
- // RandomID returns an 8 byte random string in hexadecimal.
- func RandomID() string {
- b := make([]byte, 8)
- n, _ := rand.Read(b)
- return fmt.Sprintf("%x", b[:n])
- }
|