diff --git a/src/admin/admin.go b/src/admin/admin.go index 8028bcc..5ea5ab8 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -189,22 +189,43 @@ func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) { }, errors.New("Failed to add peer") } }) - a.AddHandler("removePeer", []string{"port"}, func(in Info) (Info, error) { + a.AddHandler("disconnectPeer", []string{"port"}, func(in Info) (Info, error) { port, err := strconv.ParseInt(fmt.Sprint(in["port"]), 10, 64) if err != nil { return Info{}, err } if a.core.DisconnectPeer(uint64(port)) == nil { return Info{ - "removed": []string{ + "disconnected": []string{ fmt.Sprint(port), }, }, nil } else { return Info{ - "not_removed": []string{ + "not_disconnected": []string{ fmt.Sprint(port), }, + }, errors.New("Failed to disconnect peer") + } + }) + a.AddHandler("removePeer", []string{"uri", "[interface]"}, func(in Info) (Info, error) { + // Set sane defaults + intf := "" + // Has interface been specified? + if itf, ok := in["interface"]; ok { + intf = itf.(string) + } + if a.core.RemovePeer(in["uri"].(string), intf) == nil { + return Info{ + "removed": []string{ + in["uri"].(string), + }, + }, nil + } else { + return Info{ + "not_removed": []string{ + in["uri"].(string), + }, }, errors.New("Failed to remove peer") } }) diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index b5b8d36..13f4cb1 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -448,12 +448,31 @@ func (c *Core) AddPeer(addr string, sintf string) error { return nil } -// RemovePeer is not implemented yet. func (c *Core) RemovePeer(addr string, sintf string) error { - // TODO: Implement a reverse of AddPeer, where we look up the port number - // based on the addr and sintf, disconnect it and then remove it from the - // peers list so we don't reconnect to it later - return errors.New("not implemented") + if sintf == "" { + for i, peer := range c.config.Current.Peers { + if peer == addr { + c.config.Current.Peers = append(c.config.Current.Peers[:i], c.config.Current.Peers[i+1:]...) + break + } + } + } else if _, ok := c.config.Current.InterfacePeers[sintf]; ok { + for i, peer := range c.config.Current.InterfacePeers[sintf] { + if peer == addr { + c.config.Current.InterfacePeers[sintf] = append(c.config.Current.InterfacePeers[sintf][:i], c.config.Current.InterfacePeers[sintf][i+1:]...) + break + } + } + } + + ports := c.peers.ports.Load().(map[switchPort]*peer) + for p, peer := range ports { + if addr == peer.intf.name { + c.peers.removePeer(p) + } + } + + return nil } // CallPeer calls a peer once. This should be specified in the peer URI format,