From 9cb01da6059eef1c275b8414b7684a005b4905ad Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 10 May 2017 09:48:43 +0200 Subject: [PATCH 1/2] agent: use helper for INADDR_ANY --- command/agent/agent.go | 2 +- command/agent/command.go | 4 ++-- command/agent/config.go | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 3 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index ba15e3851a07..0684a98dcc50 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -305,7 +305,7 @@ func (a *Agent) consulConfig() (*consul.Config, error) { } a.config.AdvertiseAddr = ipStr - case a.config.BindAddr != "0.0.0.0" && a.config.BindAddr != "" && a.config.BindAddr != "[::]": + case a.config.BindAddr != "" && !isAddrANY(a.config.BindAddr): a.config.AdvertiseAddr = a.config.BindAddr default: diff --git a/command/agent/command.go b/command/agent/command.go index 4326ab4306ba..16f66e263b2b 100644 --- a/command/agent/command.go +++ b/command/agent/command.go @@ -361,12 +361,12 @@ func (c *Command) readConfig() *Config { return nil } - if config.AdvertiseAddr == "0.0.0.0" || config.AdvertiseAddr == "::" || config.AdvertiseAddr == "[::]" { + if isAddrANY(config.AdvertiseAddr) { c.UI.Error("Advertise address cannot be " + config.AdvertiseAddr) return nil } - if config.AdvertiseAddrWan == "0.0.0.0" || config.AdvertiseAddrWan == "::" || config.AdvertiseAddrWan == "[::]" { + if isAddrANY(config.AdvertiseAddrWan) { c.UI.Error("Advertise WAN address cannot be " + config.AdvertiseAddrWan) return nil } diff --git a/command/agent/config.go b/command/agent/config.go index aea7d685fdaa..71f6db7cdd79 100644 --- a/command/agent/config.go +++ b/command/agent/config.go @@ -1976,3 +1976,23 @@ func (d dirEnts) Less(i, j int) bool { func (d dirEnts) Swap(i, j int) { d[i], d[j] = d[j], d[i] } + +// isAddrANY checks if the given ip address is an IPv4 or IPv6 ANY address. ip +// can be either a *net.IP or a string. It panics on another type. +func isAddrANY(ip interface{}) bool { + if ip == nil { + return false + } + var ips string + switch x := ip.(type) { + case net.IP: + ips = x.String() + case *net.IP: + ips = x.String() + case string: + ips = x + default: + panic(fmt.Sprintf("invalid type: %T", ip)) + } + return ips == "0.0.0.0" || ips == "::" || ips == "[::]" +} From 67773734a70506d0243b38ac2bec6a6fb2781984 Mon Sep 17 00:00:00 2001 From: Frank Schroeder Date: Wed, 10 May 2017 09:30:19 +0200 Subject: [PATCH 2/2] agent: use bind address as src unless INADDR_ANY Use the bind address as source address for outgoing RPC connections unless it is INADDR_ANY. The current code uses the advertise address which will not work in certain environments where the advertise address is not routable in the network of the agent, e.g. NAT environment, container... After all, that is the purpose of the advertise address. See #2822 --- command/agent/agent.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/command/agent/agent.go b/command/agent/agent.go index 0684a98dcc50..d0230eb4c494 100644 --- a/command/agent/agent.go +++ b/command/agent/agent.go @@ -440,9 +440,10 @@ func (a *Agent) consulConfig() (*consul.Config, error) { } // set the src address for outgoing rpc connections - // to RPCAdvertise with port 0 so that outgoing - // connections use a random port. - base.RPCSrcAddr = &net.TCPAddr{IP: base.RPCAdvertise.IP} + // Use port 0 so that outgoing connections use a random port. + if !isAddrANY(base.RPCAddr.IP) { + base.RPCSrcAddr = &net.TCPAddr{IP: base.RPCAddr.IP} + } // Format the build string revision := a.config.Revision