diff --git a/cmd/agent.go b/cmd/agent.go index 2de0d7e..081e16d 100644 --- a/cmd/agent.go +++ b/cmd/agent.go @@ -46,6 +46,7 @@ var ( clusterName string ipv6 bool max int + iface string ) type server struct{} @@ -79,11 +80,14 @@ func (s *server) Leave(ctx context.Context, in *tt.NodeAddress) (*tt.Response, e // Broadcast sends an arbitrary data message to other // healthy nodes in the network. func (s *server) Broadcast(ctx context.Context, in *tt.Message) (*tt.Response, error) { + log.Debug().Msgf("Got a broadcast message with length: %d", len(in.Bytes)) if len(in.Bytes) == 0 { + log.Warn().Msgf("Cannot send an empty broadcast message! Ignoring...") return &tt.Response{Code: tt.Response_ERROR}, errors.New("Cannot send a zero byte broadcast") } err := smudge.BroadcastBytes(in.Bytes) if err != nil { + log.Warn().Msgf("Error sending message: %v", err) return &tt.Response{Code: tt.Response_ERROR}, err } log.Info().Msg("Send broadcast to the network") @@ -214,23 +218,26 @@ func (s *server) LocalAddress(ctx context.Context, in *tt.Empty) (*tt.NodeAddres // Get preferred outbound ip of this machine func getOutboundIP(ipv6 bool) (string, error) { - var ( - conn net.Conn - err error - ) - - if ipv6 { - conn, err = net.Dial("udp", "2001:4860:4860::8888") - } else { - conn, err = net.Dial("udp", "8.8.8.8:80") - } + byNameInterface, err := net.InterfaceByName(iface) if err != nil { + log.Debug().Msg("heh?") return "", err } - - defer conn.Close() - localAddr := conn.LocalAddr().(*net.UDPAddr) - return localAddr.IP.String(), nil + addresses, err := byNameInterface.Addrs() + log.Debug().Msgf("addresses for %s: %v", iface, addresses) + for k, v := range addresses { + addr := strings.Split(v.String(), "/")[0] + log.Debug().Msgf("Found interface Address #%v : %v", k, addr) + ip := net.ParseIP(addr) + if ip != nil && !ip.IsLoopback() && !ip.IsLinkLocalUnicast() { + if ipv6 && ip.To4() == nil { + return ip.String(), nil + } else if !ipv6 && ip.To4() != nil { + return ip.String(), nil + } + } + } + return "", errors.New("Cannot determine the IP address for the interface") } // agentCmd represents the agent command @@ -246,6 +253,9 @@ and listens to RPC command on the RCP interface.`, } bind = "::" } + if (bind == "0.0.0.0" || bind == "::") && iface == "" { + return errors.New("Specify the interface if you do not specify the bind address") + } return nil }, Run: func(cmd *cobra.Command, args []string) { @@ -262,13 +272,13 @@ and listens to RPC command on the RCP interface.`, } }() - // configure smudge - if bind == "0.0.0.0" { + if bind == "0.0.0.0" || bind == "::" { bind, err = getOutboundIP(ipv6) if err != nil { - log.Fatal().Msgf("Failed to determine bind address: %v", err) + log.Fatal().Msgf("Failed to guess a suitable bind address. Please manually specify a bind address on the commandline.") } } + // configure smudge ip := net.ParseIP(bind) if ip == nil { log.Fatal().Msgf("Failed to parse ip address: %s", bind) @@ -327,6 +337,7 @@ func init() { agentCmd.Flags().IntVarP(&port, "port", "p", smudge.GetListenPort(), "list port for the gossip network") agentCmd.Flags().StringVarP(&bind, "bind", "b", "0.0.0.0", "listen address for the gossip network") agentCmd.Flags().BoolVarP(&ipv6, "ipv6", "6", false, "alias for -b [::], listens to all IPv6 interfaces") + agentCmd.Flags().StringVarP(&iface, "iface", "i", "", "interface to use") agentCmd.Flags().IntVar(&hbm, "heartbeat", smudge.GetHeartbeatMillis(), "heartbeat used within the gossip network") agentCmd.Flags().IntVar(&max, "max", 0, "maximum size for broadcast messages, set to 0 means 256 for IPv4 and 512 for IPv6") agentCmd.Flags().BoolVar(&multicast, "multicast", false, "enable multicast node discovery") diff --git a/spec.yaml b/spec.yaml index 3a6adb5..e28d262 100644 --- a/spec.yaml +++ b/spec.yaml @@ -1,24 +1,24 @@ -image: docker.io/servicelaborg/tamtam:1.0.8 +image: docker.io/servicelaborg/tamtam:1.0.9 tags: ['1', '1.0', 'latest'] manifests: - - image: docker.io/servicelaborg/tamtam:1.0.8-linux-amd64 + image: docker.io/servicelaborg/tamtam:1.0.9-linux-amd64 platform: architecture: amd64 os: linux - - image: docker.io/servicelaborg/tamtam:1.0.8-linux-386 + image: docker.io/servicelaborg/tamtam:1.0.9-linux-386 platform: architecture: 386 os: linux - - image: docker.io/servicelaborg/tamtam:1.0.8-linux-arm_6 + image: docker.io/servicelaborg/tamtam:1.0.9-linux-arm_6 platform: architecture: arm variant: v6 os: linux - - image: docker.io/servicelaborg/tamtam:1.0.8-linux-arm64 + image: docker.io/servicelaborg/tamtam:1.0.9-linux-arm64 platform: architecture: arm64 variant: v8