mirror of
				https://github.com/tailscale/tailscale.git
				synced 2025-10-31 08:11:32 +01:00 
			
		
		
		
	This makes deployment easier in hetrogenous environments. Updates ENG-4274 Signed-off-by: James Tucker <james@tailscale.com>
		
			
				
	
	
		
			65 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			65 lines
		
	
	
		
			1.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| // Copyright (c) Tailscale Inc & AUTHORS
 | |
| // SPDX-License-Identifier: BSD-3-Clause
 | |
| 
 | |
| package netutil
 | |
| 
 | |
| import (
 | |
| 	"errors"
 | |
| 	"net"
 | |
| 	"net/netip"
 | |
| )
 | |
| 
 | |
| // DefaultInterfacePortable looks up the current default interface using a portable lookup method that
 | |
| // works on most systems with a BSD style socket interface.
 | |
| //
 | |
| // Returns the interface name and IP address of the default route interface.
 | |
| //
 | |
| // If the default cannot be determined, an error is returned.
 | |
| // Requires that there is a route on the system servicing UDP IPv4.
 | |
| func DefaultInterfacePortable() (string, netip.Addr, error) {
 | |
| 	// Note: UDP dial just performs a connect(2), and doesn't actually send a packet.
 | |
| 	c, err := net.Dial("udp4", "8.8.8.8:53")
 | |
| 	if err != nil {
 | |
| 		return "", netip.Addr{}, err
 | |
| 	}
 | |
| 	laddr := c.LocalAddr().(*net.UDPAddr)
 | |
| 	c.Close()
 | |
| 
 | |
| 	ifs, err := net.Interfaces()
 | |
| 	if err != nil {
 | |
| 		return "", netip.Addr{}, err
 | |
| 	}
 | |
| 
 | |
| 	var (
 | |
| 		iface *net.Interface
 | |
| 		ipnet *net.IPNet
 | |
| 	)
 | |
| 	for _, ifc := range ifs {
 | |
| 		addrs, err := ifc.Addrs()
 | |
| 		if err != nil {
 | |
| 			return "", netip.Addr{}, err
 | |
| 		}
 | |
| 		for _, addr := range addrs {
 | |
| 			if ipn, ok := addr.(*net.IPNet); ok {
 | |
| 				if ipn.Contains(laddr.IP) {
 | |
| 					if ipnet == nil {
 | |
| 						ipnet = ipn
 | |
| 						iface = &ifc
 | |
| 					} else {
 | |
| 						newSize, _ := ipn.Mask.Size()
 | |
| 						oldSize, _ := ipnet.Mask.Size()
 | |
| 						if newSize > oldSize {
 | |
| 							ipnet = ipn
 | |
| 							iface = &ifc
 | |
| 						}
 | |
| 					}
 | |
| 				}
 | |
| 			}
 | |
| 		}
 | |
| 	}
 | |
| 	if iface == nil {
 | |
| 		return "", netip.Addr{}, errors.New("no default interface")
 | |
| 	}
 | |
| 	return iface.Name, laddr.AddrPort().Addr(), nil
 | |
| }
 |