From dd05a7f2a816df8eecc5f50950097908f28b9d69 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 28 Mar 2019 19:09:19 +0000 Subject: [PATCH] Tweaks --- cmd/yggdrasil/main.go | 9 +++++---- src/multicast/multicast.go | 18 ++++++++++-------- src/yggdrasil/core.go | 35 ++++++++++++++++++----------------- src/yggdrasil/router.go | 30 +++++++++++++++--------------- src/yggdrasil/session.go | 2 +- 5 files changed, 49 insertions(+), 45 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index fe848497..72f02840 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -29,7 +29,7 @@ type Core = yggdrasil.Core type node struct { core Core - tun tuntap.TunAdapter + tuntap tuntap.TunAdapter multicast multicast.Multicast } @@ -251,13 +251,14 @@ func main() { // Now that we have a working configuration, we can now actually start // Yggdrasil. This will start the router, switch, DHT node, TCP and UDP // sockets, TUN/TAP adapter and multicast discovery port. - n.core.SetRouterAdapter(&n.tun) - if err := n.core.Start(cfg, logger); err != nil { + n.core.SetRouterAdapter(&n.tuntap) + state, err := n.core.Start(cfg, logger) + if err != nil { logger.Errorln("An error occurred during startup") panic(err) } // Start the multicast interface - n.multicast.Init(&n.core, cfg, logger) + n.multicast.Init(&n.core, state, logger, nil) if err := n.multicast.Start(); err != nil { logger.Errorln("An error occurred starting multicast:", err) } diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index 71bdbc83..c6756808 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -16,7 +16,7 @@ import ( type Multicast struct { core *yggdrasil.Core - config *config.NodeConfig + config *config.NodeState log *log.Logger reconfigure chan chan error sock *ipv6.PacketConn @@ -25,13 +25,13 @@ type Multicast struct { listenPort uint16 } -func (m *Multicast) Init(core *yggdrasil.Core, config *config.NodeConfig, log *log.Logger) { +func (m *Multicast) Init(core *yggdrasil.Core, state *config.NodeState, log *log.Logger, options interface{}) error { m.core = core - m.config = config + m.config = state m.log = log m.reconfigure = make(chan chan error, 1) m.listeners = make(map[string]*yggdrasil.TcpListener) - current := m.config //.Get() + current, _ := m.config.Get() m.listenPort = current.LinkLocalTCPPort go func() { for { @@ -44,6 +44,7 @@ func (m *Multicast) Init(core *yggdrasil.Core, config *config.NodeConfig, log *l if count := len(m.interfaces()); count != 0 { m.log.Infoln("Found", count, "multicast interface(s)") } + return nil } func (m *Multicast) Start() error { @@ -75,10 +76,13 @@ func (m *Multicast) Start() error { return nil } +func (m *Multicast) Stop() error { + return nil +} + func (m *Multicast) interfaces() map[string]net.Interface { // Get interface expressions from config - //current, _ := m.config.Get() - current := m.config + current, _ := m.config.Get() exprs := current.MulticastInterfaces // Ask the system for network interfaces interfaces := make(map[string]net.Interface) @@ -197,7 +201,6 @@ func (m *Multicast) announce() { if l, ok := m.listeners[iface.Name]; !ok || l.Listener == nil { // No listener was found - let's create one listenaddr := fmt.Sprintf("[%s%%%s]:%d", addrIP, iface.Name, m.listenPort) - //if li, err := m.core.link.tcp.listen(listenaddr); err == nil { if li, err := m.core.ListenTCP(listenaddr); err == nil { m.log.Debugln("Started multicasting on", iface.Name) // Store the listener so that we can stop it later if needed @@ -261,7 +264,6 @@ func (m *Multicast) listen() { continue } addr.Zone = "" - //if err := m.core.link.call("tcp://"+addr.String(), from.Zone); err != nil { if err := m.core.CallPeer("tcp://"+addr.String(), from.Zone); err != nil { m.log.Debugln("Call from multicast failed:", err) } diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 5d45a489..dbc893a8 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -17,11 +17,6 @@ import ( var buildName string var buildVersion string -type module interface { - init(*Core, *config.NodeConfig) error - start() error -} - // The Core object represents the Yggdrasil node. You should create a Core // object for each Yggdrasil node you plan to run. type Core struct { @@ -173,14 +168,14 @@ func GetBuildVersion() string { // Set the router adapter func (c *Core) SetRouterAdapter(adapter adapterImplementation) { - c.router.tun = adapter + c.router.adapter = adapter } // Starts up Yggdrasil using the provided NodeState, and outputs debug logging // through the provided log.Logger. The started stack will include TCP and UDP // sockets, a multicast discovery socket, an admin socket, router, switch and // DHT node. -func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { +func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) (*config.NodeState, error) { c.log = log c.config = config.NodeState{ @@ -201,7 +196,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { if err := c.link.init(c); err != nil { c.log.Errorln("Failed to start link interfaces") - return err + return nil, err } c.config.Mutex.RLock() @@ -212,34 +207,34 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { if err := c.switchTable.start(); err != nil { c.log.Errorln("Failed to start switch") - return err + return nil, err } if err := c.router.start(); err != nil { c.log.Errorln("Failed to start router") - return err + return nil, err } if err := c.admin.start(); err != nil { c.log.Errorln("Failed to start admin socket") - return err + return nil, err } - if err := c.router.tun.Start(c.router.addr, c.router.subnet); err != nil { + if err := c.router.adapter.Start(c.router.addr, c.router.subnet); err != nil { c.log.Errorln("Failed to start TUN/TAP") - return err + return nil, err } go c.addPeerLoop() c.log.Infoln("Startup complete") - return nil + return &c.config, nil } // Stops the Yggdrasil node. func (c *Core) Stop() { c.log.Infoln("Stopping...") - c.router.tun.Close() + c.router.adapter.Close() c.admin.close() } @@ -283,6 +278,12 @@ func (c *Core) GetSubnet() *net.IPNet { return &net.IPNet{IP: subnet, Mask: net.CIDRMask(64, 128)} } +// GetRouterAddresses returns the raw address and subnet types as used by the +// router +func (c *Core) GetRouterAddresses() (address.Address, address.Subnet) { + return c.router.addr, c.router.subnet +} + // Gets the nodeinfo. func (c *Core) GetNodeInfo() nodeinfoPayload { return c.router.nodeinfo.getNodeInfo() @@ -350,11 +351,11 @@ func (c *Core) GetTUNDefaultIfTAPMode() bool { // Gets the current TUN/TAP interface name. func (c *Core) GetTUNIfName() string { //return c.router.tun.iface.Name() - return c.router.tun.Name() + return c.router.adapter.Name() } // Gets the current TUN/TAP interface MTU. func (c *Core) GetTUNIfMTU() int { //return c.router.tun.mtu - return c.router.tun.MTU() + return c.router.adapter.MTU() } diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index aa2cd54b..6314cb12 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -5,7 +5,7 @@ package yggdrasil // TODO clean up old/unused code, maybe improve comments on whatever is left // Send: -// Receive a packet from the tun +// Receive a packet from the adapter // Look up session (if none exists, trigger a search) // Hand off to session (which encrypts, etc) // Session will pass it back to router.out, which hands it off to the self peer @@ -20,7 +20,7 @@ package yggdrasil // If it's dht/seach/etc. traffic, the router passes it to that part // If it's an encapsulated IPv6 packet, the router looks up the session for it // The packet is passed to the session, which decrypts it, router.recvPacket -// The router then runs some sanity checks before passing it to the tun +// The router then runs some sanity checks before passing it to the adapter import ( "bytes" @@ -31,7 +31,7 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/util" ) -// The router struct has channels to/from the tun/tap device and a self peer (0), which is how messages are passed between this node and the peers/switch layer. +// The router struct has channels to/from the adapter device and a self peer (0), which is how messages are passed between this node and the peers/switch layer. // The router's mainLoop goroutine is responsible for managing all information related to the dht, searches, and crypto sessions. type router struct { core *Core @@ -41,17 +41,17 @@ type router struct { in <-chan []byte // packets we received from the network, link to peer's "out" out func([]byte) // packets we're sending to the network, link to peer's "in" toRecv chan router_recvPacket // packets to handle via recvPacket() - tun adapterImplementation // TUN/TAP adapter - recv chan<- []byte // place where the tun pulls received packets from - send <-chan []byte // place where the tun puts outgoing packets - reject chan<- RejectedPacket // place where we send error packets back to tun + adapter adapterImplementation // TUN/TAP adapter + recv chan<- []byte // place where the adapter pulls received packets from + send <-chan []byte // place where the adapter puts outgoing packets + reject chan<- RejectedPacket // place where we send error packets back to adapter reset chan struct{} // signal that coords changed (re-init sessions/dht) admin chan func() // pass a lambda for the admin socket to query stuff cryptokey cryptokey nodeinfo nodeinfo } -// Packet and session info, used to check that the packet matches a valid IP range or CKR prefix before sending to the tun. +// Packet and session info, used to check that the packet matches a valid IP range or CKR prefix before sending to the adapter. type router_recvPacket struct { bs []byte sinfo *sessionInfo @@ -70,7 +70,7 @@ type RejectedPacket struct { Detail interface{} } -// Initializes the router struct, which includes setting up channels to/from the tun/tap. +// Initializes the router struct, which includes setting up channels to/from the adapter. func (r *router) init(core *Core) { r.core = core r.reconfigure = make(chan chan error, 1) @@ -128,7 +128,7 @@ func (r *router) init(core *Core) { r.nodeinfo.setNodeInfo(r.core.config.Current.NodeInfo, r.core.config.Current.NodeInfoPrivacy) r.core.config.Mutex.RUnlock() r.cryptokey.init(r.core) - r.tun.Init(&r.core.config, r.core.log, send, recv, reject) + r.adapter.Init(&r.core.config, r.core.log, send, recv, reject) } // Starts the mainLoop goroutine. @@ -138,7 +138,7 @@ func (r *router) start() error { return nil } -// Takes traffic from the tun/tap and passes it to router.send, or from r.in and handles incoming traffic. +// Takes traffic from the adapter and passes it to router.send, or from r.in and handles incoming traffic. // Also adds new peer info to the DHT. // Also resets the DHT and sesssions in the event of a coord change. // Also does periodic maintenance stuff. @@ -179,7 +179,7 @@ func (r *router) mainLoop() { // If a session to the destination exists, gets the session and passes the packet to it. // If no session exists, it triggers (or continues) a search. // If the session hasn't responded recently, it triggers a ping or search to keep things alive or deal with broken coords *relatively* quickly. -// It also deals with oversized packets if there are MTU issues by calling into icmpv6.go to spoof PacketTooBig traffic, or DestinationUnreachable if the other side has their tun/tap disabled. +// It also deals with oversized packets if there are MTU issues by calling into icmpv6.go to spoof PacketTooBig traffic, or DestinationUnreachable if the other side has their adapter disabled. func (r *router) sendPacket(bs []byte) { var sourceAddr address.Address var destAddr address.Address @@ -339,7 +339,7 @@ func (r *router) sendPacket(bs []byte) { } // Called for incoming traffic by the session worker for that connection. -// Checks that the IP address is correct (matches the session) and passes the packet to the tun/tap. +// Checks that the IP address is correct (matches the session) and passes the packet to the adapter. func (r *router) recvPacket(bs []byte, sinfo *sessionInfo) { // Note: called directly by the session worker, not the router goroutine if len(bs) < 24 { @@ -402,7 +402,7 @@ func (r *router) handleIn(packet []byte) { } // Handles incoming traffic, i.e. encapuslated ordinary IPv6 packets. -// Passes them to the crypto session worker to be decrypted and sent to the tun/tap. +// Passes them to the crypto session worker to be decrypted and sent to the adapter. func (r *router) handleTraffic(packet []byte) { defer util.PutBytes(packet) p := wire_trafficPacket{} @@ -436,7 +436,7 @@ func (r *router) handleProto(packet []byte) { return } // Now do something with the bytes in bs... - // send dht messages to dht, sessionRefresh to sessions, data to tun... + // send dht messages to dht, sessionRefresh to sessions, data to adapter... // For data, should check that key and IP match... bsType, bsTypeLen := wire_decode_uint64(bs) if bsTypeLen == 0 { diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index b3563e05..8deff953 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -277,7 +277,7 @@ func (ss *sessions) createSession(theirPermKey *crypto.BoxPubKey) *sessionInfo { sinfo.mySesPriv = *priv sinfo.myNonce = *crypto.NewBoxNonce() sinfo.theirMTU = 1280 - sinfo.myMTU = uint16(ss.core.router.tun.MTU()) + sinfo.myMTU = uint16(ss.core.router.adapter.MTU()) now := time.Now() sinfo.time = now sinfo.mtuTime = now