diff --git a/src/yggdrasil/mobile.go b/src/yggdrasil/mobile.go index 5cd15ece..b7510613 100644 --- a/src/yggdrasil/mobile.go +++ b/src/yggdrasil/mobile.go @@ -3,9 +3,7 @@ package yggdrasil import ( - "encoding/hex" "encoding/json" - "errors" "log" "os" "regexp" @@ -14,7 +12,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/crypto" "github.com/yggdrasil-network/yggdrasil-go/src/util" ) @@ -43,6 +40,7 @@ func (c *Core) addStaticPeers(cfg *config.NodeConfig) { } } +// Starts a node with a randomly generated config. func (c *Core) StartAutoconfigure() error { mobilelog := MobileLogger{} logger := log.New(mobilelog, "", 0) @@ -64,6 +62,8 @@ func (c *Core) StartAutoconfigure() error { return nil } +// Starts a node with the given JSON config. You can get JSON config (rather +// than HJSON) by using the GenerateConfigJSON() function. func (c *Core) StartJSON(configjson []byte) error { mobilelog := MobileLogger{} logger := log.New(mobilelog, "", 0) @@ -92,6 +92,7 @@ func (c *Core) StartJSON(configjson []byte) error { return nil } +// Generates mobile-friendly configuration in JSON format. func GenerateConfigJSON() []byte { nc := config.GenerateConfig(false) nc.IfName = "dummy" @@ -102,90 +103,30 @@ func GenerateConfigJSON() []byte { } } +// Gets the node's IPv6 address. func (c *Core) GetAddressString() string { return c.GetAddress().String() } +// Gets the node's IPv6 subnet in CIDR notation. func (c *Core) GetSubnetString() string { return c.GetSubnet().String() } +// Wait for a packet from the router. You will use this when implementing a +// dummy adapter in place of real TUN - when this call returns a packet, you +// will probably want to give it to the OS to write to TUN. func (c *Core) RouterRecvPacket() ([]byte, error) { packet := <-c.router.tun.recv return packet, nil } +// Send a packet to the router. You will use this when implementing a +// dummy adapter in place of real TUN - when the operating system tells you +// that a new packet is available from TUN, call this function to give it to +// Yggdrasil. func (c *Core) RouterSendPacket(buf []byte) error { packet := append(util.GetBytes(), buf[:]...) c.router.tun.send <- packet return nil } - -func (c *Core) AWDLCreateInterface(boxPubKey string, sigPubKey string, name string) error { - fromAWDL := make(chan []byte, 32) - toAWDL := make(chan []byte, 32) - - var boxPub crypto.BoxPubKey - var sigPub crypto.SigPubKey - boxPubHex, err := hex.DecodeString(boxPubKey) - if err != nil { - c.log.Println(err) - return err - } - sigPubHex, err := hex.DecodeString(sigPubKey) - if err != nil { - c.log.Println(err) - return err - } - copy(boxPub[:], boxPubHex) - copy(sigPub[:], sigPubHex) - - if intf, err := c.awdl.create(fromAWDL, toAWDL, &boxPub, &sigPub, name); err == nil { - if intf != nil { - c.log.Println(err) - return err - } else { - c.log.Println("c.awdl.create didn't return an interface") - return errors.New("c.awdl.create didn't return an interface") - } - } else { - c.log.Println(err) - return err - } -} - -func (c *Core) AWDLCreateInterfaceFromContext(context []byte, name string) error { - if len(context) < crypto.BoxPubKeyLen+crypto.SigPubKeyLen { - return errors.New("Not enough bytes in context") - } - boxPubKey := hex.EncodeToString(context[:crypto.BoxPubKeyLen]) - sigPubKey := hex.EncodeToString(context[crypto.BoxPubKeyLen:]) - return c.AWDLCreateInterface(boxPubKey, sigPubKey, name) -} - -func (c *Core) AWDLShutdownInterface(name string) error { - return c.awdl.shutdown(name) -} - -func (c *Core) AWDLRecvPacket(identity string) ([]byte, error) { - if intf := c.awdl.getInterface(identity); intf != nil { - return <-intf.toAWDL, nil - } - return nil, errors.New("AWDLRecvPacket identity not known: " + identity) -} - -func (c *Core) AWDLSendPacket(identity string, buf []byte) error { - packet := append(util.GetBytes(), buf[:]...) - if intf := c.awdl.getInterface(identity); intf != nil { - intf.fromAWDL <- packet - return nil - } - return errors.New("AWDLSendPacket identity not known: " + identity) -} - -func (c *Core) AWDLConnectionContext() []byte { - var context []byte - context = append(context, c.boxPub[:]...) - context = append(context, c.sigPub[:]...) - return context -} diff --git a/src/yggdrasil/mobile_ios.go b/src/yggdrasil/mobile_ios.go index 4abc6e9f..6d2570db 100644 --- a/src/yggdrasil/mobile_ios.go +++ b/src/yggdrasil/mobile_ios.go @@ -12,7 +12,14 @@ void Log(const char *text) { } */ import "C" -import "unsafe" +import ( + "encoding/hex" + "errors" + "unsafe" + + "github.com/yggdrasil-network/yggdrasil-go/src/crypto" + "github.com/yggdrasil-network/yggdrasil-go/src/util" +) type MobileLogger struct { } @@ -23,3 +30,72 @@ func (nsl MobileLogger) Write(p []byte) (n int, err error) { C.Log(cstr) return len(p), nil } + +func (c *Core) AWDLCreateInterface(boxPubKey string, sigPubKey string, name string) error { + fromAWDL := make(chan []byte, 32) + toAWDL := make(chan []byte, 32) + + var boxPub crypto.BoxPubKey + var sigPub crypto.SigPubKey + boxPubHex, err := hex.DecodeString(boxPubKey) + if err != nil { + c.log.Println(err) + return err + } + sigPubHex, err := hex.DecodeString(sigPubKey) + if err != nil { + c.log.Println(err) + return err + } + copy(boxPub[:], boxPubHex) + copy(sigPub[:], sigPubHex) + + if intf, err := c.awdl.create(fromAWDL, toAWDL, &boxPub, &sigPub, name); err == nil { + if intf != nil { + c.log.Println(err) + return err + } else { + c.log.Println("c.awdl.create didn't return an interface") + return errors.New("c.awdl.create didn't return an interface") + } + } else { + c.log.Println(err) + return err + } +} + +func (c *Core) AWDLCreateInterfaceFromContext(context []byte, name string) error { + if len(context) < crypto.BoxPubKeyLen+crypto.SigPubKeyLen { + return errors.New("Not enough bytes in context") + } + boxPubKey := hex.EncodeToString(context[:crypto.BoxPubKeyLen]) + sigPubKey := hex.EncodeToString(context[crypto.BoxPubKeyLen:]) + return c.AWDLCreateInterface(boxPubKey, sigPubKey, name) +} + +func (c *Core) AWDLShutdownInterface(name string) error { + return c.awdl.shutdown(name) +} + +func (c *Core) AWDLRecvPacket(identity string) ([]byte, error) { + if intf := c.awdl.getInterface(identity); intf != nil { + return <-intf.toAWDL, nil + } + return nil, errors.New("AWDLRecvPacket identity not known: " + identity) +} + +func (c *Core) AWDLSendPacket(identity string, buf []byte) error { + packet := append(util.GetBytes(), buf[:]...) + if intf := c.awdl.getInterface(identity); intf != nil { + intf.fromAWDL <- packet + return nil + } + return errors.New("AWDLSendPacket identity not known: " + identity) +} + +func (c *Core) AWDLConnectionContext() []byte { + var context []byte + context = append(context, c.boxPub[:]...) + context = append(context, c.sigPub[:]...) + return context +}