From de1005e4fa95405073993eafb17f99d25d35246c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 27 Jul 2019 15:00:09 +0100 Subject: [PATCH] Various API changes and simplifications to fix mobile builds --- src/admin/admin.go | 4 +-- src/config/config.go | 32 ++++++++++++++++---- src/dummy/dummy.go | 61 -------------------------------------- src/mobile/mobile.go | 10 +++---- src/multicast/multicast.go | 4 +-- src/tuntap/ckr.go | 2 +- src/tuntap/conn.go | 4 +-- src/tuntap/tun.go | 2 +- src/tuntap/tun_dummy.go | 19 ------------ src/yggdrasil/api.go | 28 +++++++---------- src/yggdrasil/conn.go | 13 ++++++-- src/yggdrasil/core.go | 4 +-- src/yggdrasil/router.go | 2 +- 13 files changed, 63 insertions(+), 122 deletions(-) delete mode 100644 src/dummy/dummy.go delete mode 100644 src/tuntap/tun_dummy.go diff --git a/src/admin/admin.go b/src/admin/admin.go index fc8a6a5..7d6f16b 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -60,7 +60,7 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log. go func() { for { e := <-a.reconfigure - current, previous := state.Get() + current, previous := state.GetCurrent(), state.GetPrevious() if current.AdminListen != previous.AdminListen { a.listenaddr = current.AdminListen a.Stop() @@ -69,7 +69,7 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log. e <- nil } }() - current, _ := state.Get() + current := state.GetCurrent() a.listenaddr = current.AdminListen a.AddHandler("list", []string{}, func(in Info) (Info, error) { handlers := make(map[string]interface{}) diff --git a/src/config/config.go b/src/config/config.go index 9f8f3f5..a7bbbac 100644 --- a/src/config/config.go +++ b/src/config/config.go @@ -16,21 +16,27 @@ type NodeState struct { Mutex sync.RWMutex } -// Get returns both the current and previous node configs -func (s *NodeState) Get() (NodeConfig, NodeConfig) { +// Current returns the current node config +func (s *NodeState) GetCurrent() NodeConfig { s.Mutex.RLock() defer s.Mutex.RUnlock() - return s.Current, s.Previous + return s.Current +} + +// Previous returns the previous node config +func (s *NodeState) GetPrevious() NodeConfig { + s.Mutex.RLock() + defer s.Mutex.RUnlock() + return s.Previous } // Replace the node configuration with new configuration. This method returns // both the new and the previous node configs -func (s *NodeState) Replace(n NodeConfig) (NodeConfig, NodeConfig) { +func (s *NodeState) Replace(n NodeConfig) { s.Mutex.Lock() defer s.Mutex.Unlock() s.Previous = s.Current s.Current = n - return s.Current, s.Previous } // NodeConfig defines all configuration values needed to run a signle yggdrasil node @@ -115,3 +121,19 @@ func GenerateConfig() *NodeConfig { return &cfg } + +// NewEncryptionKeys generates a new encryption keypair. The encryption keys are +// used to encrypt traffic and to derive the IPv6 address/subnet of the node. +func (cfg *NodeConfig) NewEncryptionKeys() { + bpub, bpriv := crypto.NewBoxKeys() + cfg.EncryptionPublicKey = hex.EncodeToString(bpub[:]) + cfg.EncryptionPrivateKey = hex.EncodeToString(bpriv[:]) +} + +// NewSigningKeys generates a new signing keypair. The signing keys are used to +// derive the structure of the spanning tree. +func (cfg *NodeConfig) NewSigningKeys() { + spub, spriv := crypto.NewSigKeys() + cfg.SigningPublicKey = hex.EncodeToString(spub[:]) + cfg.SigningPrivateKey = hex.EncodeToString(spriv[:]) +} diff --git a/src/dummy/dummy.go b/src/dummy/dummy.go deleted file mode 100644 index ca6bb7b..0000000 --- a/src/dummy/dummy.go +++ /dev/null @@ -1,61 +0,0 @@ -package dummy - -import ( - "github.com/gologme/log" - "github.com/yggdrasil-network/yggdrasil-go/src/address" - "github.com/yggdrasil-network/yggdrasil-go/src/config" - "github.com/yggdrasil-network/yggdrasil-go/src/defaults" - "github.com/yggdrasil-network/yggdrasil-go/src/util" - "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" -) - -// DummyAdapter is a non-specific adapter that is used by the mobile APIs. -// You can also use it to send or receive custom traffic over Yggdrasil. -type DummyAdapter struct { - yggdrasil.Adapter -} - -// Init initialises the dummy adapter. -func (m *DummyAdapter) Init(config *config.NodeState, log *log.Logger, send chan<- []byte, recv <-chan []byte, reject <-chan yggdrasil.RejectedPacket) { - m.Adapter.Init(config, log, send, recv, reject) -} - -// Name returns the name of the adapter. This is always "dummy" for dummy -// adapters. -func (m *DummyAdapter) Name() string { - return "dummy" -} - -// MTU gets the adapter's MTU. This returns your platform's maximum MTU for -// dummy adapters. -func (m *DummyAdapter) MTU() int { - return defaults.GetDefaults().MaximumIfMTU -} - -// IsTAP always returns false for dummy adapters. -func (m *DummyAdapter) IsTAP() bool { - return false -} - -// Recv waits for and returns for a packet from the router. -func (m *DummyAdapter) Recv() ([]byte, error) { - packet := <-m.Adapter.Recv - return packet, nil -} - -// Send a packet to the router. -func (m *DummyAdapter) Send(buf []byte) error { - packet := append(util.GetBytes(), buf[:]...) - m.Adapter.Send <- packet - return nil -} - -// Start is not implemented for dummy adapters. -func (m *DummyAdapter) Start(address.Address, address.Subnet) error { - return nil -} - -// Close is not implemented for dummy adapters. -func (m *DummyAdapter) Close() error { - return nil -} diff --git a/src/mobile/mobile.go b/src/mobile/mobile.go index 02bd30f..08a8c1a 100644 --- a/src/mobile/mobile.go +++ b/src/mobile/mobile.go @@ -10,7 +10,6 @@ import ( hjson "github.com/hjson/hjson-go" "github.com/mitchellh/mapstructure" "github.com/yggdrasil-network/yggdrasil-go/src/config" - "github.com/yggdrasil-network/yggdrasil-go/src/dummy" "github.com/yggdrasil-network/yggdrasil-go/src/multicast" "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" ) @@ -24,7 +23,6 @@ type Yggdrasil struct { core yggdrasil.Core multicast multicast.Multicast log MobileLogger - dummy.DummyAdapter } func (m *Yggdrasil) addStaticPeers(cfg *config.NodeConfig) { @@ -59,10 +57,10 @@ func (m *Yggdrasil) StartAutoconfigure() error { if hostname, err := os.Hostname(); err == nil { nc.NodeInfo = map[string]interface{}{"name": hostname} } - if err := m.core.SetRouterAdapter(m); err != nil { + /*if err := m.core.SetRouterAdapter(m); err != nil { logger.Errorln("An error occured setting router adapter:", err) return err - } + }*/ state, err := m.core.Start(nc, logger) if err != nil { logger.Errorln("An error occured starting Yggdrasil:", err) @@ -92,10 +90,10 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error { return err } nc.IfName = "dummy" - if err := m.core.SetRouterAdapter(m); err != nil { + /*if err := m.core.SetRouterAdapter(m); err != nil { logger.Errorln("An error occured setting router adapter:", err) return err - } + }*/ state, err := m.core.Start(nc, logger) if err != nil { logger.Errorln("An error occured starting Yggdrasil:", err) diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index ba1f18f..5ab9673 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -35,7 +35,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log m.config = state m.log = log m.listeners = make(map[string]*yggdrasil.TcpListener) - current, _ := m.config.Get() + current := m.config.GetCurrent() m.listenPort = current.LinkLocalTCPPort m.groupAddr = "[ff02::114]:9001" return nil @@ -92,7 +92,7 @@ func (m *Multicast) UpdateConfig(config *config.NodeConfig) { func (m *Multicast) Interfaces() map[string]net.Interface { interfaces := make(map[string]net.Interface) // Get interface expressions from config - current, _ := m.config.Get() + current := m.config.GetCurrent() exprs := current.MulticastInterfaces // Ask the system for network interfaces allifaces, err := net.Interfaces() diff --git a/src/tuntap/ckr.go b/src/tuntap/ckr.go index 52c1159..80e3e42 100644 --- a/src/tuntap/ckr.go +++ b/src/tuntap/ckr.go @@ -59,7 +59,7 @@ func (c *cryptokey) init(tun *TunAdapter) { // Configure the CKR routes - this must only ever be called from the router // goroutine, e.g. through router.doAdmin func (c *cryptokey) configure() error { - current, _ := c.tun.config.Get() + current := c.tun.config.GetCurrent() // Set enabled/disabled state c.setEnabled(current.TunnelRouting.Enable) diff --git a/src/tuntap/conn.go b/src/tuntap/conn.go index 193c623..1d47b37 100644 --- a/src/tuntap/conn.go +++ b/src/tuntap/conn.go @@ -108,10 +108,10 @@ func (s *tunConn) writer() error { } else { s.tun.log.Errorln(s.conn.String(), "TUN/TAP generic write error:", err) } - } else if ispackettoobig, maxsize := e.PacketTooBig(); ispackettoobig { + } else if e.PacketTooBig() { // TODO: This currently isn't aware of IPv4 for CKR ptb := &icmp.PacketTooBig{ - MTU: int(maxsize), + MTU: int(e.PacketMaximumSize()), Data: b[:900], } if packet, err := CreateICMPv6(b[8:24], b[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil { diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index cc12497..eef05b8 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -119,7 +119,7 @@ func (tun *TunAdapter) Init(config *config.NodeState, log *log.Logger, listener // Start the setup process for the TUN/TAP adapter. If successful, starts the // read/write goroutines to handle packets on that interface. func (tun *TunAdapter) Start() error { - current, _ := tun.config.Get() + current := tun.config.GetCurrent() if tun.config == nil || tun.listener == nil || tun.dialer == nil { return errors.New("No configuration available to TUN/TAP") } diff --git a/src/tuntap/tun_dummy.go b/src/tuntap/tun_dummy.go deleted file mode 100644 index 04e6525..0000000 --- a/src/tuntap/tun_dummy.go +++ /dev/null @@ -1,19 +0,0 @@ -// +build mobile - -package tuntap - -// This is to catch unsupported platforms -// If your platform supports tun devices, you could try configuring it manually - -// Creates the TUN/TAP adapter, if supported by the Water library. Note that -// no guarantees are made at this point on an unsupported platform. -func (tun *TunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { - tun.mtu = getSupportedMTU(mtu) - return tun.setupAddress(addr) -} - -// We don't know how to set the IPv6 address on an unknown platform, therefore -// write about it to stdout and don't try to do anything further. -func (tun *TunAdapter) setupAddress(addr string) error { - return nil -} diff --git a/src/yggdrasil/api.go b/src/yggdrasil/api.go index 1bec983..bd0d098 100644 --- a/src/yggdrasil/api.go +++ b/src/yggdrasil/api.go @@ -290,18 +290,6 @@ func (c *Core) ListenTCP(uri string) (*TcpListener, error) { return c.link.tcp.listen(uri) } -// NewEncryptionKeys generates a new encryption keypair. The encryption keys are -// used to encrypt traffic and to derive the IPv6 address/subnet of the node. -func (c *Core) NewEncryptionKeys() (*crypto.BoxPubKey, *crypto.BoxPrivKey) { - return crypto.NewBoxKeys() -} - -// NewSigningKeys generates a new signing keypair. The signing keys are used to -// derive the structure of the spanning tree. -func (c *Core) NewSigningKeys() (*crypto.SigPubKey, *crypto.SigPrivKey) { - return crypto.NewSigKeys() -} - // NodeID gets the node ID. func (c *Core) NodeID() *crypto.NodeID { return crypto.GetNodeID(&c.boxPub) @@ -343,12 +331,6 @@ func (c *Core) Subnet() *net.IPNet { return &net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)} } -// RouterAddresses returns the raw address and subnet types as used by the -// router -func (c *Core) RouterAddresses() (address.Address, address.Subnet) { - return c.router.addr, c.router.subnet -} - // NodeInfo gets the currently configured nodeinfo. func (c *Core) MyNodeInfo() nodeinfoPayload { return c.router.nodeinfo.getNodeInfo() @@ -473,6 +455,16 @@ func (c *Core) DisconnectPeer(port uint64) error { return nil } +// RouterAddress returns the raw address as used by the router. +func (c *Core) RouterAddress() address.Address { + return c.router.addr +} + +// RouterSubnet returns the raw address as used by the router. +func (c *Core) RouterSubnet() address.Subnet { + return c.router.subnet +} + // GetAllowedEncryptionPublicKeys returns the public keys permitted for incoming // peer connections. func (c *Core) GetAllowedEncryptionPublicKeys() []string { diff --git a/src/yggdrasil/conn.go b/src/yggdrasil/conn.go index bc884fb..cd61e24 100644 --- a/src/yggdrasil/conn.go +++ b/src/yggdrasil/conn.go @@ -35,8 +35,17 @@ func (e *ConnError) Temporary() bool { // PacketTooBig returns in response to sending a packet that is too large, and // if so, the maximum supported packet size that should be used for the // connection. -func (e *ConnError) PacketTooBig() (bool, int) { - return e.maxsize > 0, e.maxsize +func (e *ConnError) PacketTooBig() bool { + return e.maxsize > 0 +} + +// PacketMaximumSize returns the maximum supported packet size. This will only +// return a non-zero value if ConnError.PacketTooBig() returns true. +func (e *ConnError) PacketMaximumSize() int { + if !e.PacketTooBig() { + return 0 + } + return e.maxsize } // Closed returns if the session is already closed and is now unusable. diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 35a86df..2aa7834 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -45,7 +45,7 @@ func (c *Core) init() error { c.log = log.New(ioutil.Discard, "", 0) } - current, _ := c.config.Get() + current := c.config.GetCurrent() boxPrivHex, err := hex.DecodeString(current.EncryptionPrivateKey) if err != nil { @@ -94,7 +94,7 @@ func (c *Core) init() error { func (c *Core) addPeerLoop() { for { // the peers from the config - these could change! - current, _ := c.config.Get() + current := c.config.GetCurrent() // Add peers from the Peers section for _, peer := range current.Peers { diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index 514d14f..abd31cb 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -132,7 +132,7 @@ func (r *router) mainLoop() { case f := <-r.admin: f() case e := <-r.reconfigure: - current, _ := r.core.config.Get() + current := r.core.config.GetCurrent() e <- r.nodeinfo.setNodeInfo(current.NodeInfo, current.NodeInfoPrivacy) } }