From 9d9083e3733417383139cf9bcd7f5907faf8cbeb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 23 May 2018 11:28:20 +0100 Subject: [PATCH] Update configuration names, fix multicast interface selection --- misc/sim/treesim.go | 16 ++--- src/yggdrasil/admin.go | 24 ++++---- src/yggdrasil/config/config.go | 27 +++++---- src/yggdrasil/debug.go | 8 +-- src/yggdrasil/multicast.go | 103 ++++++++++++++++----------------- src/yggdrasil/peer.go | 26 ++++----- src/yggdrasil/tcp.go | 2 +- src/yggdrasil/udp.go | 2 +- yggdrasil.go | 30 +++++----- yggdrasilctl.go | 4 +- 10 files changed, 117 insertions(+), 125 deletions(-) diff --git a/misc/sim/treesim.go b/misc/sim/treesim.go index 91aa2234..9b2d0af5 100644 --- a/misc/sim/treesim.go +++ b/misc/sim/treesim.go @@ -48,16 +48,16 @@ func (n *Node) startPeers() { func linkNodes(m, n *Node) { // Don't allow duplicates - if m.core.DEBUG_getPeers().DEBUG_hasPeer(n.core.DEBUG_getSigPub()) { + if m.core.DEBUG_getPeers().DEBUG_hasPeer(n.core.DEBUG_getSigningPublicKey()) { return } // Create peers // Buffering reduces packet loss in the sim // This slightly speeds up testing (fewer delays before retrying a ping) - p := m.core.DEBUG_getPeers().DEBUG_newPeer(n.core.DEBUG_getBoxPub(), - n.core.DEBUG_getSigPub()) - q := n.core.DEBUG_getPeers().DEBUG_newPeer(m.core.DEBUG_getBoxPub(), - m.core.DEBUG_getSigPub()) + p := m.core.DEBUG_getPeers().DEBUG_newPeer(n.core.DEBUG_getEncryptionPublicKey(), + n.core.DEBUG_getSigningPublicKey()) + q := n.core.DEBUG_getPeers().DEBUG_newPeer(m.core.DEBUG_getEncryptionPublicKey(), + m.core.DEBUG_getSigningPublicKey()) DEBUG_simLinkPeers(p, q) return } @@ -141,7 +141,7 @@ func startNetwork(store map[[32]byte]*Node) { func getKeyedStore(store map[int]*Node) map[[32]byte]*Node { newStore := make(map[[32]byte]*Node) for _, node := range store { - newStore[node.core.DEBUG_getSigPub()] = node + newStore[node.core.DEBUG_getSigningPublicKey()] = node } return newStore } @@ -257,7 +257,7 @@ func pingNodes(store map[[32]byte]*Node) { count++ //if count > 16 { break } fmt.Printf("Sending packets from node %d/%d (%d)\n", count, nNodes, source.index) - sourceKey := source.core.DEBUG_getBoxPub() + sourceKey := source.core.DEBUG_getEncryptionPublicKey() payload := sourceKey[:] sourceAddr := source.core.DEBUG_getAddr()[:] sendTo := func(bs []byte, destAddr []byte) { @@ -329,7 +329,7 @@ func pingBench(store map[[32]byte]*Node) { return packet } for _, dest := range store { - key := dest.core.DEBUG_getBoxPub() + key := dest.core.DEBUG_getEncryptionPublicKey() loc := dest.core.DEBUG_getLocator() coords := loc.DEBUG_getCoords() ping := getPing(key, coords) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index b6bc7f38..a2b5944d 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -173,11 +173,11 @@ func (a *admin) init(c *Core, listenaddr string) { }, nil } }) - a.addHandler("getAllowedBoxPubs", []string{}, func(in admin_info) (admin_info, error) { - return admin_info{"allowed_box_pubs": a.getAllowedBoxPubs()}, nil + a.addHandler("getAllowedEncryptionPublicKeys", []string{}, func(in admin_info) (admin_info, error) { + return admin_info{"allowed_box_pubs": a.getAllowedEncryptionPublicKeys()}, nil }) - a.addHandler("addAllowedBoxPub", []string{"box_pub_key"}, func(in admin_info) (admin_info, error) { - if a.addAllowedBoxPub(in["box_pub_key"].(string)) == nil { + a.addHandler("addAllowedEncryptionPublicKey", []string{"box_pub_key"}, func(in admin_info) (admin_info, error) { + if a.addAllowedEncryptionPublicKey(in["box_pub_key"].(string)) == nil { return admin_info{ "added": []string{ in["box_pub_key"].(string), @@ -191,8 +191,8 @@ func (a *admin) init(c *Core, listenaddr string) { }, errors.New("Failed to add allowed box pub key") } }) - a.addHandler("removeAllowedBoxPub", []string{"box_pub_key"}, func(in admin_info) (admin_info, error) { - if a.removeAllowedBoxPub(in["box_pub_key"].(string)) == nil { + a.addHandler("removeAllowedEncryptionPublicKey", []string{"box_pub_key"}, func(in admin_info) (admin_info, error) { + if a.removeAllowedEncryptionPublicKey(in["box_pub_key"].(string)) == nil { return admin_info{ "removed": []string{ in["box_pub_key"].(string), @@ -514,8 +514,8 @@ func (a *admin) getData_getSessions() []admin_nodeInfo { return infos } -func (a *admin) getAllowedBoxPubs() []string { - pubs := a.core.peers.getAllowedBoxPubs() +func (a *admin) getAllowedEncryptionPublicKeys() []string { + pubs := a.core.peers.getAllowedEncryptionPublicKeys() var out []string for _, pub := range pubs { out = append(out, hex.EncodeToString(pub[:])) @@ -523,22 +523,22 @@ func (a *admin) getAllowedBoxPubs() []string { return out } -func (a *admin) addAllowedBoxPub(bstr string) (err error) { +func (a *admin) addAllowedEncryptionPublicKey(bstr string) (err error) { boxBytes, err := hex.DecodeString(bstr) if err == nil { var box boxPubKey copy(box[:], boxBytes) - a.core.peers.addAllowedBoxPub(&box) + a.core.peers.addAllowedEncryptionPublicKey(&box) } return } -func (a *admin) removeAllowedBoxPub(bstr string) (err error) { +func (a *admin) removeAllowedEncryptionPublicKey(bstr string) (err error) { boxBytes, err := hex.DecodeString(bstr) if err == nil { var box boxPubKey copy(box[:], boxBytes) - a.core.peers.removeAllowedBoxPub(&box) + a.core.peers.removeAllowedEncryptionPublicKey(&box) } return } diff --git a/src/yggdrasil/config/config.go b/src/yggdrasil/config/config.go index 3d2e408b..b06f341c 100644 --- a/src/yggdrasil/config/config.go +++ b/src/yggdrasil/config/config.go @@ -2,20 +2,19 @@ package config // NodeConfig defines all configuration values needed to run a signle yggdrasil node type NodeConfig struct { - Listen string `comment:"Listen address for peer connections (default is to listen for all\nconnections over IPv4 and IPv6)"` - AdminListen string `comment:"Listen address for admin connections (default is to listen only\nfor local connections)"` - Peers []string `comment:"List of connection strings for static peers (i.e. tcp://a.b.c.d:e)"` - AllowedBoxPubs []string `json:"AllowedEncryptionPublicKeys" comment:"List of peer encryption public keys to allow UDP incoming TCP connections from\n(if left empty/undefined then connections will be allowed by default)"` - BoxPub string `json:"EncryptionPublicKey" comment:"Your public encryption key (your peers may ask you for this to put\ninto their AllowedEncryptionPublicKeys configuration)"` - BoxPriv string `json:"EncryptionPrivateKey" comment:"Your private encryption key (do not share this with anyone!)"` - SigPub string `json:"SigningPublicKey" comment:"Your public signing key"` - SigPriv string `json:"SigningPrivateKey" comment:"Your private signing key (do not share this with anyone!)"` - Multicast bool `json:"MulticastEnabled,omitempty" comment:"Enable or disable automatic peer discovery on the same LAN using multicast"` - LinkLocal []string `json:"MulticastInterfaces" comment:"Regexes for which interfaces multicast peer discovery should be enabled\non. If none specified, multicast peer discovery is disabled"` - IfName string `comment:"Local network interface name for TUN/TAP adapter, or \"auto\", or \"none\""` - IfTAPMode bool `comment:"Set local network interface to TAP mode rather than TUN mode (if supported\nby your platform, option will be ignored if not)"` - IfMTU int `comment:"Maximux Transmission Unit (MTU) size for your local network interface"` - Net NetConfig `comment:"Extended options for interoperability with other networks"` + Listen string `comment:"Listen address for peer connections (default is to listen for all\nconnections over IPv4 and IPv6)"` + AdminListen string `comment:"Listen address for admin connections (default is to listen only\nfor local connections)"` + Peers []string `comment:"List of connection strings for static peers (i.e. tcp://a.b.c.d:e)"` + AllowedEncryptionPublicKeys []string `comment:"List of peer encryption public keys to allow UDP incoming TCP connections from\n(if left empty/undefined then connections will be allowed by default)"` + EncryptionPublicKey string `comment:"Your public encryption key (your peers may ask you for this to put\ninto their AllowedEncryptionPublicKeys configuration)"` + EncryptionPrivateKey string `comment:"Your private encryption key (do not share this with anyone!)"` + SigningPublicKey string `comment:"Your public signing key"` + SigningPrivateKey string `comment:"Your private signing key (do not share this with anyone!)"` + MulticastInterfaces []string `comment:"Regexes for which interfaces multicast peer discovery should be enabled\non. If none specified, multicast peer discovery is disabled"` + IfName string `comment:"Local network interface name for TUN/TAP adapter, or \"auto\", or \"none\""` + IfTAPMode bool `comment:"Set local network interface to TAP mode rather than TUN mode (if supported\nby your platform, option will be ignored if not)"` + IfMTU int `comment:"Maximux Transmission Unit (MTU) size for your local network interface"` + Net NetConfig `comment:"Extended options for interoperability with other networks"` } // NetConfig defines network/proxy related configuration values diff --git a/src/yggdrasil/debug.go b/src/yggdrasil/debug.go index 7b270825..3106691f 100644 --- a/src/yggdrasil/debug.go +++ b/src/yggdrasil/debug.go @@ -17,11 +17,11 @@ import "regexp" // Core -func (c *Core) DEBUG_getSigPub() sigPubKey { +func (c *Core) DEBUG_getSigningPublicKey() sigPubKey { return (sigPubKey)(c.sigPub) } -func (c *Core) DEBUG_getBoxPub() boxPubKey { +func (c *Core) DEBUG_getEncryptionPublicKey() boxPubKey { return (boxPubKey)(c.boxPub) } @@ -404,8 +404,8 @@ func (c *Core) DEBUG_setIfceExpr(expr *regexp.Regexp) { c.ifceExpr = append(c.ifceExpr, expr) } -func (c *Core) DEBUG_addAllowedBoxPub(boxStr string) { - err := c.admin.addAllowedBoxPub(boxStr) +func (c *Core) DEBUG_addAllowedEncryptionPublicKey(boxStr string) { + err := c.admin.addAllowedEncryptionPublicKey(boxStr) if err != nil { panic(err) } diff --git a/src/yggdrasil/multicast.go b/src/yggdrasil/multicast.go index 80dbf079..a37b022d 100644 --- a/src/yggdrasil/multicast.go +++ b/src/yggdrasil/multicast.go @@ -7,69 +7,67 @@ import "fmt" import "golang.org/x/net/ipv6" type multicast struct { - core *Core - sock *ipv6.PacketConn - groupAddr string - interfaces []net.Interface + core *Core + sock *ipv6.PacketConn + groupAddr string + interfaces []net.Interface } func (m *multicast) init(core *Core) { m.core = core m.groupAddr = "[ff02::114]:9001" - // Ask the system for network interfaces - allifaces, err := net.Interfaces() - if err != nil { - panic(err) - } - // Work out which interfaces to announce on - for _, iface := range allifaces { - if iface.Flags & net.FlagUp == 0 { - // Ignore interfaces that are down - continue - } - if iface.Flags & net.FlagMulticast == 0 { - // Ignore non-multicast interfaces - continue - } - if iface.Flags & net.FlagPointToPoint != 0 { - // Ignore point-to-point interfaces - continue - } - for _, expr := range m.core.ifceExpr { - m.core.log.Println(expr) - if expr.MatchString(iface.Name) { - m.core.log.Println(iface.Name, "matched", expr) - m.interfaces = append(m.interfaces, iface) - } - } - } - m.core.log.Println("Found", len(m.interfaces), "multicast interfaces") + // Ask the system for network interfaces + allifaces, err := net.Interfaces() + if err != nil { + panic(err) + } + // Work out which interfaces to announce on + for _, iface := range allifaces { + if iface.Flags&net.FlagUp == 0 { + // Ignore interfaces that are down + continue + } + if iface.Flags&net.FlagMulticast == 0 { + // Ignore non-multicast interfaces + continue + } + if iface.Flags&net.FlagPointToPoint != 0 { + // Ignore point-to-point interfaces + continue + } + for _, expr := range m.core.ifceExpr { + if expr.MatchString(iface.Name) { + m.interfaces = append(m.interfaces, iface) + } + } + } + m.core.log.Println("Found", len(m.interfaces), "multicast interface(s)") } func (m *multicast) Start() { if len(m.core.ifceExpr) == 0 { - m.core.log.Println("Not starting multicast discovery") + m.core.log.Println("Multicast discovery is disabled") } else { - m.core.log.Println("Starting multicast discovery...") - addr, err := net.ResolveUDPAddr("udp", m.groupAddr) - if err != nil { - panic(err) - } - listenString := fmt.Sprintf("[::]:%v", addr.Port) - conn, err := net.ListenPacket("udp6", listenString) - if err != nil { - panic(err) - } - //defer conn.Close() // Let it close on its own when the application exits - m.sock = ipv6.NewPacketConn(conn) - if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil { - // Windows can't set this flag, so we need to handle it in other ways - //panic(err) - } + m.core.log.Println("Multicast discovery is enabled") + addr, err := net.ResolveUDPAddr("udp", m.groupAddr) + if err != nil { + panic(err) + } + listenString := fmt.Sprintf("[::]:%v", addr.Port) + conn, err := net.ListenPacket("udp6", listenString) + if err != nil { + panic(err) + } + //defer conn.Close() // Let it close on its own when the application exits + m.sock = ipv6.NewPacketConn(conn) + if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil { + // Windows can't set this flag, so we need to handle it in other ways + //panic(err) + } - go m.listen() - go m.announce() - } + go m.listen() + go m.announce() + } } func (m *multicast) announce() { @@ -86,7 +84,6 @@ func (m *multicast) announce() { } for { for _, iface := range m.interfaces { - m.sock.JoinGroup(&iface, groupAddr) //err := n.sock.JoinGroup(&iface, groupAddr) //if err != nil { panic(err) } diff --git a/src/yggdrasil/peer.go b/src/yggdrasil/peer.go index 9325c331..4ce1a780 100644 --- a/src/yggdrasil/peer.go +++ b/src/yggdrasil/peer.go @@ -34,8 +34,8 @@ type peers struct { mutex sync.Mutex // Synchronize writes to atomic ports atomic.Value //map[Port]*peer, use CoW semantics //ports map[Port]*peer - authMutex sync.RWMutex - allowedBoxPubs map[boxPubKey]struct{} + authMutex sync.RWMutex + allowedEncryptionPublicKeys map[boxPubKey]struct{} } func (ps *peers) init(c *Core) { @@ -43,33 +43,33 @@ func (ps *peers) init(c *Core) { defer ps.mutex.Unlock() ps.putPorts(make(map[switchPort]*peer)) ps.core = c - ps.allowedBoxPubs = make(map[boxPubKey]struct{}) + ps.allowedEncryptionPublicKeys = make(map[boxPubKey]struct{}) } -func (ps *peers) isAllowedBoxPub(box *boxPubKey) bool { +func (ps *peers) isAllowedEncryptionPublicKey(box *boxPubKey) bool { ps.authMutex.RLock() defer ps.authMutex.RUnlock() - _, isIn := ps.allowedBoxPubs[*box] - return isIn || len(ps.allowedBoxPubs) == 0 + _, isIn := ps.allowedEncryptionPublicKeys[*box] + return isIn || len(ps.allowedEncryptionPublicKeys) == 0 } -func (ps *peers) addAllowedBoxPub(box *boxPubKey) { +func (ps *peers) addAllowedEncryptionPublicKey(box *boxPubKey) { ps.authMutex.Lock() defer ps.authMutex.Unlock() - ps.allowedBoxPubs[*box] = struct{}{} + ps.allowedEncryptionPublicKeys[*box] = struct{}{} } -func (ps *peers) removeAllowedBoxPub(box *boxPubKey) { +func (ps *peers) removeAllowedEncryptionPublicKey(box *boxPubKey) { ps.authMutex.Lock() defer ps.authMutex.Unlock() - delete(ps.allowedBoxPubs, *box) + delete(ps.allowedEncryptionPublicKeys, *box) } -func (ps *peers) getAllowedBoxPubs() []boxPubKey { +func (ps *peers) getAllowedEncryptionPublicKeys() []boxPubKey { ps.authMutex.RLock() defer ps.authMutex.RUnlock() - keys := make([]boxPubKey, 0, len(ps.allowedBoxPubs)) - for key := range ps.allowedBoxPubs { + keys := make([]boxPubKey, 0, len(ps.allowedEncryptionPublicKeys)) + for key := range ps.allowedEncryptionPublicKeys { keys = append(keys, key) } return keys diff --git a/src/yggdrasil/tcp.go b/src/yggdrasil/tcp.go index 7aafca31..869b6afd 100644 --- a/src/yggdrasil/tcp.go +++ b/src/yggdrasil/tcp.go @@ -151,7 +151,7 @@ func (iface *tcpInterface) handler(sock net.Conn, incoming bool) { return } // Check if we're authorized to connect to this key / IP - if incoming && !iface.core.peers.isAllowedBoxPub(&info.box) { + if incoming && !iface.core.peers.isAllowedEncryptionPublicKey(&info.box) { // Allow unauthorized peers if they're link-local raddrStr, _, _ := net.SplitHostPort(sock.RemoteAddr().String()) raddr := net.ParseIP(raddrStr) diff --git a/src/yggdrasil/udp.go b/src/yggdrasil/udp.go index 6eeabdc8..81f5d38b 100644 --- a/src/yggdrasil/udp.go +++ b/src/yggdrasil/udp.go @@ -206,7 +206,7 @@ func (iface *udpInterface) handleKeys(msg []byte, addr connAddr) { udpAddr := addr.toUDPAddr() // Check if we're authorized to connect to this key / IP // TODO monitor and always allow outgoing connections - if !iface.core.peers.isAllowedBoxPub(&ks.box) { + if !iface.core.peers.isAllowedEncryptionPublicKey(&ks.box) { // Allow unauthorized peers if they're link-local if !udpAddr.IP.IsLinkLocalUnicast() { return diff --git a/yggdrasil.go b/yggdrasil.go index 2877dfdb..900f3a92 100644 --- a/yggdrasil.go +++ b/yggdrasil.go @@ -32,19 +32,19 @@ type node struct { } func (n *node) init(cfg *nodeConfig, logger *log.Logger) { - boxPub, err := hex.DecodeString(cfg.BoxPub) + boxPub, err := hex.DecodeString(cfg.EncryptionPublicKey) if err != nil { panic(err) } - boxPriv, err := hex.DecodeString(cfg.BoxPriv) + boxPriv, err := hex.DecodeString(cfg.EncryptionPrivateKey) if err != nil { panic(err) } - sigPub, err := hex.DecodeString(cfg.SigPub) + sigPub, err := hex.DecodeString(cfg.SigningPublicKey) if err != nil { panic(err) } - sigPriv, err := hex.DecodeString(cfg.SigPriv) + sigPriv, err := hex.DecodeString(cfg.SigningPrivateKey) if err != nil { panic(err) } @@ -58,17 +58,14 @@ func (n *node) init(cfg *nodeConfig, logger *log.Logger) { logger.Println("Starting admin socket...") n.core.DEBUG_setupAndStartAdminInterface(cfg.AdminListen) logger.Println("Started admin socket") - for _, pBoxStr := range cfg.AllowedBoxPubs { - n.core.DEBUG_addAllowedBoxPub(pBoxStr) + for _, pBoxStr := range cfg.AllowedEncryptionPublicKeys { + n.core.DEBUG_addAllowedEncryptionPublicKey(pBoxStr) } - logger.Println(cfg.LinkLocal) - for _, ll := range cfg.LinkLocal { - logger.Println("Adding expression", ll) + for _, ll := range cfg.MulticastInterfaces { ifceExpr, err := regexp.Compile(ll) if err != nil { panic(err) } - logger.Println("Added expression", ifceExpr) n.core.DEBUG_setIfceExpr(ifceExpr) } n.core.DEBUG_setupAndStartMulticastInterface() @@ -99,14 +96,13 @@ func generateConfig(isAutoconf bool) *nodeConfig { cfg.Listen = fmt.Sprintf("[::]:%d", r1.Intn(65534-32768)+32768) } cfg.AdminListen = "[::1]:9001" - cfg.BoxPub = hex.EncodeToString(bpub[:]) - cfg.BoxPriv = hex.EncodeToString(bpriv[:]) - cfg.SigPub = hex.EncodeToString(spub[:]) - cfg.SigPriv = hex.EncodeToString(spriv[:]) + cfg.EncryptionPublicKey = hex.EncodeToString(bpub[:]) + cfg.EncryptionPrivateKey = hex.EncodeToString(bpriv[:]) + cfg.SigningPublicKey = hex.EncodeToString(spub[:]) + cfg.SigningPrivateKey = hex.EncodeToString(spriv[:]) cfg.Peers = []string{} - cfg.AllowedBoxPubs = []string{} - cfg.Multicast = false - cfg.LinkLocal = []string{} + cfg.AllowedEncryptionPublicKeys = []string{} + cfg.MulticastInterfaces = []string{".*"} cfg.IfName = core.DEBUG_GetTUNDefaultIfName() cfg.IfMTU = core.DEBUG_GetTUNDefaultIfMTU() cfg.IfTAPMode = core.DEBUG_GetTUNDefaultIfTAPMode() diff --git a/yggdrasilctl.go b/yggdrasilctl.go index 2fbebf71..7a6654a6 100644 --- a/yggdrasilctl.go +++ b/yggdrasilctl.go @@ -155,7 +155,7 @@ func main() { fmt.Println("TAP mode:", tap_mode) } } - case "addPeer", "removePeer", "addAllowedBoxPub", "removeAllowedBoxPub": + case "addPeer", "removePeer", "addAllowedEncryptionPublicKey", "removeAllowedEncryptionPublicKey": if _, ok := res["added"]; ok { for _, v := range res["added"].([]interface{}) { fmt.Println("Added:", fmt.Sprint(v)) @@ -176,7 +176,7 @@ func main() { fmt.Println("Not removed:", fmt.Sprint(v)) } } - case "getAllowedBoxPubs": + case "getAllowedEncryptionPublicKeys": if _, ok := res["allowed_box_pubs"]; !ok { fmt.Println("All connections are allowed") } else if res["allowed_box_pubs"] == nil {