Skip to content

Commit

Permalink
feat(mdns): allow specifying iface for mDNS
Browse files Browse the repository at this point in the history
  • Loading branch information
badrabubker committed Jul 8, 2024
1 parent fca5ddd commit 7a57b61
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 3 deletions.
22 changes: 20 additions & 2 deletions cmd/serf/command/agent/command.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ func (c *Command) readConfig() *Config {
"tag pair, specified as key=value")
cmdFlags.StringVar(&cmdConfig.Discover, "discover", "", "mDNS discovery name")
cmdFlags.StringVar(&cmdConfig.Interface, "iface", "", "interface to bind to")
cmdFlags.StringVar(&cmdConfig.MDNS.Interface, "mdns-iface", "", "interface to use for mDNS")
cmdFlags.StringVar(&cmdConfig.TagsFile, "tags-file", "", "tag persistence file")
cmdFlags.BoolVar(&cmdConfig.EnableSyslog, "syslog", false,
"enable logging to syslog facility")
Expand Down Expand Up @@ -176,6 +177,18 @@ func (c *Command) readConfig() *Config {
return nil
}

if config.MDNS.Interface != "" {
if config.Discover == "" {
c.Ui.Error("mDNS interface specified without enabling mDNS discovery")
return nil
}

if _, err := net.InterfaceByName(config.MDNS.Interface); err != nil {
c.Ui.Error(fmt.Sprintf("Invalid mDNS network interface: %s", err))
return nil
}
}

// Backward compatibility hack for 'Role'
if config.Role != "" {
c.Ui.Output("Deprecation warning: 'Role' has been replaced with 'Tags'")
Expand Down Expand Up @@ -432,7 +445,9 @@ func (c *Command) startAgent(config *Config, agent *Agent,
local := agent.Serf().Memberlist().LocalNode()

// Get the bind interface if any
iface, _ := config.NetworkInterface()
iface, _ := config.MDNSNetworkInterface()

c.logger.Printf("[INFO] agent: Starting mDNS listener on interface %s", iface.Name)

_, err := NewAgentMDNS(agent, logOutput, config.ReplayOnJoin,
config.NodeName, config.Discover, iface, local.Addr, int(local.Port))
Expand Down Expand Up @@ -734,7 +749,10 @@ Options:
-bind if the interface is known but not the address.
If both are provided, then Serf verifies that the
interface has the bind address that is provided. This
flag also sets the multicast device used for -discover.
flag also sets the multicast device used for -discover,
if mdns-iface is not specified.
-mdns-iface Network interface to use for mDNS. If not provided, the
-iface value is used.
-advertise=0.0.0.0 Address to advertise to the other cluster members
-config-file=foo Path to a JSON file to read configuration from.
This can be specified multiple times.
Expand Down
25 changes: 24 additions & 1 deletion cmd/serf/command/agent/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,12 @@ func DefaultConfig() *Config {

type dirEnts []os.FileInfo

type MDNSConfig struct {
// Interface is used to provide a binding interface to use for mDNS.
// if not set, iface will be used.
Interface string `mapstructure:"interface"`
}

// Config is the configuration that can be set for an Agent. Some of these
// configurations are exposed as command-line flags to `serf agent`, whereas
// many of the more advanced configurations can only be set by creating
Expand Down Expand Up @@ -154,10 +160,12 @@ type Config struct {
// allows Serf agents to join each other with zero configuration.
Discover string `mapstructure:"discover"`

MDNS MDNSConfig `mapstructure:"mdns"`

// Interface is used to provide a binding interface to use. It can be
// used instead of providing a bind address, as Serf will discover the
// address of the provided interface. It is also used to set the multicast
// device used with `-discover`.
// device used with `-discover`, if `mdns-iface` is not set
Interface string `mapstructure:"interface"`

// ReconnectIntervalRaw is the string reconnect interval time. This interval
Expand Down Expand Up @@ -292,6 +300,16 @@ func (c *Config) NetworkInterface() (*net.Interface, error) {
return net.InterfaceByName(c.Interface)
}

func (c *Config) MDNSNetworkInterface() (*net.Interface, error) {
if c.MDNS.Interface == "" && c.Interface == "" {
return nil, nil
} else if c.MDNS.Interface != "" {
return net.InterfaceByName(c.MDNS.Interface)
} else {
return net.InterfaceByName(c.Interface)
}
}

// DecodeConfig reads the configuration from the given reader in JSON
// format and decodes it into a proper Config structure.
func DecodeConfig(r io.Reader) (*Config, error) {
Expand Down Expand Up @@ -436,6 +454,11 @@ func MergeConfig(a, b *Config) *Config {
if b.Interface != "" {
result.Interface = b.Interface
}

if b.MDNS.Interface != "" {
result.MDNS.Interface = b.MDNS.Interface
}

if b.ReconnectInterval != 0 {
result.ReconnectInterval = b.ReconnectInterval
}
Expand Down

0 comments on commit 7a57b61

Please sign in to comment.