github.com/brahmaroutu/docker@v1.2.1-0.20160809185609-eb28dde01f16/daemon/cluster/listen_addr_others.go (about)

     1  // +build !linux
     2  
     3  package cluster
     4  
     5  import "net"
     6  
     7  func (c *Cluster) resolveSystemAddr() (net.IP, error) {
     8  	// Use the system's only IP address, or fail if there are
     9  	// multiple addresses to choose from.
    10  	interfaces, err := net.Interfaces()
    11  	if err != nil {
    12  		return nil, err
    13  	}
    14  
    15  	var systemAddr net.IP
    16  	var systemInterface string
    17  
    18  	// List Docker-managed subnets
    19  	v4Subnets := c.config.NetworkSubnetsProvider.V4Subnets()
    20  	v6Subnets := c.config.NetworkSubnetsProvider.V6Subnets()
    21  
    22  ifaceLoop:
    23  	for _, intf := range interfaces {
    24  		// Skip inactive interfaces and loopback interfaces
    25  		if (intf.Flags&net.FlagUp == 0) || (intf.Flags&net.FlagLoopback) != 0 {
    26  			continue
    27  		}
    28  
    29  		addrs, err := intf.Addrs()
    30  		if err != nil {
    31  			continue
    32  		}
    33  
    34  		var interfaceAddr4, interfaceAddr6 net.IP
    35  
    36  		for _, addr := range addrs {
    37  			ipAddr, ok := addr.(*net.IPNet)
    38  
    39  			// Skip loopback and link-local addresses
    40  			if !ok || !ipAddr.IP.IsGlobalUnicast() {
    41  				continue
    42  			}
    43  
    44  			if ipAddr.IP.To4() != nil {
    45  				// IPv4
    46  
    47  				// Ignore addresses in subnets that are managed by Docker.
    48  				for _, subnet := range v4Subnets {
    49  					if subnet.Contains(ipAddr.IP) {
    50  						continue ifaceLoop
    51  					}
    52  				}
    53  
    54  				if interfaceAddr4 != nil {
    55  					return nil, errMultipleIPs(intf.Name, intf.Name, interfaceAddr4, ipAddr.IP)
    56  				}
    57  
    58  				interfaceAddr4 = ipAddr.IP
    59  			} else {
    60  				// IPv6
    61  
    62  				// Ignore addresses in subnets that are managed by Docker.
    63  				for _, subnet := range v6Subnets {
    64  					if subnet.Contains(ipAddr.IP) {
    65  						continue ifaceLoop
    66  					}
    67  				}
    68  
    69  				if interfaceAddr6 != nil {
    70  					return nil, errMultipleIPs(intf.Name, intf.Name, interfaceAddr6, ipAddr.IP)
    71  				}
    72  
    73  				interfaceAddr6 = ipAddr.IP
    74  			}
    75  		}
    76  
    77  		// In the case that this interface has exactly one IPv4 address
    78  		// and exactly one IPv6 address, favor IPv4 over IPv6.
    79  		if interfaceAddr4 != nil {
    80  			if systemAddr != nil {
    81  				return nil, errMultipleIPs(systemInterface, intf.Name, systemAddr, interfaceAddr4)
    82  			}
    83  			systemAddr = interfaceAddr4
    84  			systemInterface = intf.Name
    85  		} else if interfaceAddr6 != nil {
    86  			if systemAddr != nil {
    87  				return nil, errMultipleIPs(systemInterface, intf.Name, systemAddr, interfaceAddr6)
    88  			}
    89  			systemAddr = interfaceAddr6
    90  			systemInterface = intf.Name
    91  		}
    92  	}
    93  
    94  	if systemAddr == nil {
    95  		return nil, errNoIP
    96  	}
    97  
    98  	return systemAddr, nil
    99  }