5
0
mirror of https://github.com/cwinfo/yggdrasil-go.git synced 2024-09-20 06:02:34 +00:00

Various API changes and simplifications to fix mobile builds

This commit is contained in:
Neil Alexander 2019-07-27 15:00:09 +01:00
parent 9b99f0b5e4
commit de1005e4fa
No known key found for this signature in database
GPG Key ID: A02A2019A2BB0944
13 changed files with 63 additions and 122 deletions

View File

@ -60,7 +60,7 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.
go func() { go func() {
for { for {
e := <-a.reconfigure e := <-a.reconfigure
current, previous := state.Get() current, previous := state.GetCurrent(), state.GetPrevious()
if current.AdminListen != previous.AdminListen { if current.AdminListen != previous.AdminListen {
a.listenaddr = current.AdminListen a.listenaddr = current.AdminListen
a.Stop() a.Stop()
@ -69,7 +69,7 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.
e <- nil e <- nil
} }
}() }()
current, _ := state.Get() current := state.GetCurrent()
a.listenaddr = current.AdminListen a.listenaddr = current.AdminListen
a.AddHandler("list", []string{}, func(in Info) (Info, error) { a.AddHandler("list", []string{}, func(in Info) (Info, error) {
handlers := make(map[string]interface{}) handlers := make(map[string]interface{})

View File

@ -16,21 +16,27 @@ type NodeState struct {
Mutex sync.RWMutex Mutex sync.RWMutex
} }
// Get returns both the current and previous node configs // Current returns the current node config
func (s *NodeState) Get() (NodeConfig, NodeConfig) { func (s *NodeState) GetCurrent() NodeConfig {
s.Mutex.RLock() s.Mutex.RLock()
defer s.Mutex.RUnlock() 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 // Replace the node configuration with new configuration. This method returns
// both the new and the previous node configs // 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() s.Mutex.Lock()
defer s.Mutex.Unlock() defer s.Mutex.Unlock()
s.Previous = s.Current s.Previous = s.Current
s.Current = n s.Current = n
return s.Current, s.Previous
} }
// NodeConfig defines all configuration values needed to run a signle yggdrasil node // NodeConfig defines all configuration values needed to run a signle yggdrasil node
@ -115,3 +121,19 @@ func GenerateConfig() *NodeConfig {
return &cfg 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[:])
}

View File

@ -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
}

View File

@ -10,7 +10,6 @@ import (
hjson "github.com/hjson/hjson-go" hjson "github.com/hjson/hjson-go"
"github.com/mitchellh/mapstructure" "github.com/mitchellh/mapstructure"
"github.com/yggdrasil-network/yggdrasil-go/src/config" "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/multicast"
"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil" "github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
) )
@ -24,7 +23,6 @@ type Yggdrasil struct {
core yggdrasil.Core core yggdrasil.Core
multicast multicast.Multicast multicast multicast.Multicast
log MobileLogger log MobileLogger
dummy.DummyAdapter
} }
func (m *Yggdrasil) addStaticPeers(cfg *config.NodeConfig) { func (m *Yggdrasil) addStaticPeers(cfg *config.NodeConfig) {
@ -59,10 +57,10 @@ func (m *Yggdrasil) StartAutoconfigure() error {
if hostname, err := os.Hostname(); err == nil { if hostname, err := os.Hostname(); err == nil {
nc.NodeInfo = map[string]interface{}{"name": hostname} 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) logger.Errorln("An error occured setting router adapter:", err)
return err return err
} }*/
state, err := m.core.Start(nc, logger) state, err := m.core.Start(nc, logger)
if err != nil { if err != nil {
logger.Errorln("An error occured starting Yggdrasil:", err) logger.Errorln("An error occured starting Yggdrasil:", err)
@ -92,10 +90,10 @@ func (m *Yggdrasil) StartJSON(configjson []byte) error {
return err return err
} }
nc.IfName = "dummy" 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) logger.Errorln("An error occured setting router adapter:", err)
return err return err
} }*/
state, err := m.core.Start(nc, logger) state, err := m.core.Start(nc, logger)
if err != nil { if err != nil {
logger.Errorln("An error occured starting Yggdrasil:", err) logger.Errorln("An error occured starting Yggdrasil:", err)

View File

@ -35,7 +35,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log
m.config = state m.config = state
m.log = log m.log = log
m.listeners = make(map[string]*yggdrasil.TcpListener) m.listeners = make(map[string]*yggdrasil.TcpListener)
current, _ := m.config.Get() current := m.config.GetCurrent()
m.listenPort = current.LinkLocalTCPPort m.listenPort = current.LinkLocalTCPPort
m.groupAddr = "[ff02::114]:9001" m.groupAddr = "[ff02::114]:9001"
return nil return nil
@ -92,7 +92,7 @@ func (m *Multicast) UpdateConfig(config *config.NodeConfig) {
func (m *Multicast) Interfaces() map[string]net.Interface { func (m *Multicast) Interfaces() map[string]net.Interface {
interfaces := make(map[string]net.Interface) interfaces := make(map[string]net.Interface)
// Get interface expressions from config // Get interface expressions from config
current, _ := m.config.Get() current := m.config.GetCurrent()
exprs := current.MulticastInterfaces exprs := current.MulticastInterfaces
// Ask the system for network interfaces // Ask the system for network interfaces
allifaces, err := net.Interfaces() allifaces, err := net.Interfaces()

View File

@ -59,7 +59,7 @@ func (c *cryptokey) init(tun *TunAdapter) {
// Configure the CKR routes - this must only ever be called from the router // Configure the CKR routes - this must only ever be called from the router
// goroutine, e.g. through router.doAdmin // goroutine, e.g. through router.doAdmin
func (c *cryptokey) configure() error { func (c *cryptokey) configure() error {
current, _ := c.tun.config.Get() current := c.tun.config.GetCurrent()
// Set enabled/disabled state // Set enabled/disabled state
c.setEnabled(current.TunnelRouting.Enable) c.setEnabled(current.TunnelRouting.Enable)

View File

@ -108,10 +108,10 @@ func (s *tunConn) writer() error {
} else { } else {
s.tun.log.Errorln(s.conn.String(), "TUN/TAP generic write error:", err) 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 // TODO: This currently isn't aware of IPv4 for CKR
ptb := &icmp.PacketTooBig{ ptb := &icmp.PacketTooBig{
MTU: int(maxsize), MTU: int(e.PacketMaximumSize()),
Data: b[:900], Data: b[:900],
} }
if packet, err := CreateICMPv6(b[8:24], b[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil { if packet, err := CreateICMPv6(b[8:24], b[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb); err == nil {

View File

@ -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 // Start the setup process for the TUN/TAP adapter. If successful, starts the
// read/write goroutines to handle packets on that interface. // read/write goroutines to handle packets on that interface.
func (tun *TunAdapter) Start() error { func (tun *TunAdapter) Start() error {
current, _ := tun.config.Get() current := tun.config.GetCurrent()
if tun.config == nil || tun.listener == nil || tun.dialer == nil { if tun.config == nil || tun.listener == nil || tun.dialer == nil {
return errors.New("No configuration available to TUN/TAP") return errors.New("No configuration available to TUN/TAP")
} }

View File

@ -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
}

View File

@ -290,18 +290,6 @@ func (c *Core) ListenTCP(uri string) (*TcpListener, error) {
return c.link.tcp.listen(uri) 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. // NodeID gets the node ID.
func (c *Core) NodeID() *crypto.NodeID { func (c *Core) NodeID() *crypto.NodeID {
return crypto.GetNodeID(&c.boxPub) 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)} 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. // NodeInfo gets the currently configured nodeinfo.
func (c *Core) MyNodeInfo() nodeinfoPayload { func (c *Core) MyNodeInfo() nodeinfoPayload {
return c.router.nodeinfo.getNodeInfo() return c.router.nodeinfo.getNodeInfo()
@ -473,6 +455,16 @@ func (c *Core) DisconnectPeer(port uint64) error {
return nil 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 // GetAllowedEncryptionPublicKeys returns the public keys permitted for incoming
// peer connections. // peer connections.
func (c *Core) GetAllowedEncryptionPublicKeys() []string { func (c *Core) GetAllowedEncryptionPublicKeys() []string {

View File

@ -35,8 +35,17 @@ func (e *ConnError) Temporary() bool {
// PacketTooBig returns in response to sending a packet that is too large, and // 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 // if so, the maximum supported packet size that should be used for the
// connection. // connection.
func (e *ConnError) PacketTooBig() (bool, int) { func (e *ConnError) PacketTooBig() bool {
return e.maxsize > 0, e.maxsize 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. // Closed returns if the session is already closed and is now unusable.

View File

@ -45,7 +45,7 @@ func (c *Core) init() error {
c.log = log.New(ioutil.Discard, "", 0) c.log = log.New(ioutil.Discard, "", 0)
} }
current, _ := c.config.Get() current := c.config.GetCurrent()
boxPrivHex, err := hex.DecodeString(current.EncryptionPrivateKey) boxPrivHex, err := hex.DecodeString(current.EncryptionPrivateKey)
if err != nil { if err != nil {
@ -94,7 +94,7 @@ func (c *Core) init() error {
func (c *Core) addPeerLoop() { func (c *Core) addPeerLoop() {
for { for {
// the peers from the config - these could change! // the peers from the config - these could change!
current, _ := c.config.Get() current := c.config.GetCurrent()
// Add peers from the Peers section // Add peers from the Peers section
for _, peer := range current.Peers { for _, peer := range current.Peers {

View File

@ -132,7 +132,7 @@ func (r *router) mainLoop() {
case f := <-r.admin: case f := <-r.admin:
f() f()
case e := <-r.reconfigure: case e := <-r.reconfigure:
current, _ := r.core.config.Get() current := r.core.config.GetCurrent()
e <- r.nodeinfo.setNodeInfo(current.NodeInfo, current.NodeInfoPrivacy) e <- r.nodeinfo.setNodeInfo(current.NodeInfo, current.NodeInfoPrivacy)
} }
} }