From 10157483f9bd36a5b02ee20569c908f6d8d75914 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 17:35:02 +0000 Subject: [PATCH 1/9] Move tunDevice into router --- src/yggdrasil/admin.go | 18 +++++++++--------- src/yggdrasil/core.go | 10 ++++------ src/yggdrasil/router.go | 14 ++++++++++---- src/yggdrasil/session.go | 2 +- 4 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index 266d5a89..e80ca398 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -160,9 +160,9 @@ func (a *admin) init(c *Core, listenaddr string) { }() return admin_info{ - a.core.tun.iface.Name(): admin_info{ - "tap_mode": a.core.tun.iface.IsTAP(), - "mtu": a.core.tun.mtu, + a.core.router.tun.iface.Name(): admin_info{ + "tap_mode": a.core.router.tun.iface.IsTAP(), + "mtu": a.core.router.tun.mtu, }, }, nil }) @@ -185,8 +185,8 @@ func (a *admin) init(c *Core, listenaddr string) { return admin_info{}, errors.New("Failed to configure adapter") } else { return admin_info{ - a.core.tun.iface.Name(): admin_info{ - "tap_mode": a.core.tun.iface.IsTAP(), + a.core.router.tun.iface.Name(): admin_info{ + "tap_mode": a.core.router.tun.iface.IsTAP(), "mtu": ifmtu, }, }, nil @@ -539,12 +539,12 @@ func (a *admin) removePeer(p string) error { // startTunWithMTU creates the tun/tap device, sets its address, and sets the MTU to the provided value. func (a *admin) startTunWithMTU(ifname string, iftapmode bool, ifmtu int) error { // Close the TUN first if open - _ = a.core.tun.close() + _ = a.core.router.tun.close() // Then reconfigure and start it addr := a.core.router.addr straddr := fmt.Sprintf("%s/%v", net.IP(addr[:]).String(), 8*len(address_prefix)-1) if ifname != "none" { - err := a.core.tun.setup(ifname, iftapmode, straddr, ifmtu) + err := a.core.router.tun.setup(ifname, iftapmode, straddr, ifmtu) if err != nil { return err } @@ -559,9 +559,9 @@ func (a *admin) startTunWithMTU(ifname string, iftapmode bool, ifmtu int) error a.core.sessions.sendPingPong(sinfo, false) } // Aaaaand... go! - go a.core.tun.read() + go a.core.router.tun.read() } - go a.core.tun.write() + go a.core.router.tun.write() return nil } diff --git a/src/yggdrasil/core.go b/src/yggdrasil/core.go index 5ab91a74..13609ce6 100644 --- a/src/yggdrasil/core.go +++ b/src/yggdrasil/core.go @@ -28,7 +28,6 @@ type Core struct { sessions sessions router router dht dht - tun tunDevice admin admin searches searches multicast multicast @@ -59,7 +58,6 @@ func (c *Core) init(bpub *boxPubKey, c.peers.init(c) c.router.init(c) c.switchTable.init(c, c.sigPub) // TODO move before peers? before router? - c.tun.init(c) } // Get the current build name. This is usually injected if built from git, @@ -188,7 +186,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { } ip := net.IP(c.router.addr[:]).String() - if err := c.tun.start(nc.IfName, nc.IfTAPMode, fmt.Sprintf("%s/%d", ip, 8*len(address_prefix)-1), nc.IfMTU); err != nil { + if err := c.router.tun.start(nc.IfName, nc.IfTAPMode, fmt.Sprintf("%s/%d", ip, 8*len(address_prefix)-1), nc.IfMTU); err != nil { c.log.Println("Failed to start TUN/TAP") return err } @@ -200,7 +198,7 @@ func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) error { // Stops the Yggdrasil node. func (c *Core) Stop() { c.log.Println("Stopping...") - c.tun.close() + c.router.tun.close() c.admin.close() } @@ -293,10 +291,10 @@ func (c *Core) GetTUNDefaultIfTAPMode() bool { // Gets the current TUN/TAP interface name. func (c *Core) GetTUNIfName() string { - return c.tun.iface.Name() + return c.router.tun.iface.Name() } // Gets the current TUN/TAP interface MTU. func (c *Core) GetTUNIfMTU() int { - return c.tun.mtu + return c.router.tun.mtu } diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index b4824767..eab18b1e 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -30,6 +30,10 @@ import ( "golang.org/x/net/ipv6" ) +type adapter struct { + tunDevice +} + // 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's mainLoop goroutine is responsible for managing all information related to the dht, searches, and crypto sessions. type router struct { @@ -39,6 +43,7 @@ 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 tunDevice // TUN/TAP adapter recv chan<- []byte // place where the tun pulls received packets from send <-chan []byte // place where the tun puts outgoing packets reset chan struct{} // signal that coords changed (re-init sessions/dht) @@ -75,11 +80,12 @@ func (r *router) init(core *Core) { send := make(chan []byte, 32) r.recv = recv r.send = send - r.core.tun.recv = recv - r.core.tun.send = send + r.tun.recv = recv + r.tun.send = send r.reset = make(chan struct{}, 1) r.admin = make(chan func(), 32) r.cryptokey.init(r.core) + r.tun.init(r.core) // go r.mainLoop() } @@ -279,7 +285,7 @@ func (r *router) sendPacket(bs []byte) { } // Create the ICMPv6 response from it - icmpv6Buf, err := r.core.tun.icmpv6.create_icmpv6_tun( + icmpv6Buf, err := r.tun.icmpv6.create_icmpv6_tun( bs[8:24], bs[24:40], ipv6.ICMPTypeDestinationUnreachable, 1, ptb) if err == nil { @@ -304,7 +310,7 @@ func (r *router) sendPacket(bs []byte) { } // Create the ICMPv6 response from it - icmpv6Buf, err := r.core.tun.icmpv6.create_icmpv6_tun( + icmpv6Buf, err := r.tun.icmpv6.create_icmpv6_tun( bs[8:24], bs[24:40], ipv6.ICMPTypePacketTooBig, 0, ptb) if err == nil { diff --git a/src/yggdrasil/session.go b/src/yggdrasil/session.go index 92ae262b..4f2bedf9 100644 --- a/src/yggdrasil/session.go +++ b/src/yggdrasil/session.go @@ -273,7 +273,7 @@ func (ss *sessions) createSession(theirPermKey *boxPubKey) *sessionInfo { sinfo.mySesPriv = *priv sinfo.myNonce = *newBoxNonce() sinfo.theirMTU = 1280 - sinfo.myMTU = uint16(ss.core.tun.mtu) + sinfo.myMTU = uint16(ss.core.router.tun.mtu) now := time.Now() sinfo.time = now sinfo.mtuTime = now From ccf6ce07a444f8acdc3cba86db16ff89c59d1c43 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 17:49:42 +0000 Subject: [PATCH 2/9] Fix Peers and InterfacePeers when not in correct format --- cmd/yggdrasil/main.go | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 5b756908..ec8c7125 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -12,6 +12,7 @@ import ( "os" "os/signal" "regexp" + "strings" "syscall" "time" @@ -188,6 +189,25 @@ func main() { } } } + // Check to see if the peers are in a parsable format, if not then default + // them to the TCP scheme + for index, peer := range dat["Peers"].([]interface{}) { + uri := peer.(string) + if strings.HasPrefix(uri, "tcp://") || strings.HasPrefix(uri, "socks://") { + continue + } + (dat["Peers"].([]interface{}))[index] = "tcp://" + uri + } + // Now do the same with the interface peers + for intf, peers := range dat["InterfacePeers"].(map[string]interface{}) { + for index, peer := range peers.([]interface{}) { + uri := peer.(string) + if strings.HasPrefix(uri, "tcp://") || strings.HasPrefix(uri, "socks://") { + continue + } + ((dat["InterfacePeers"].(map[string]interface{}))[intf]).([]interface{})[index] = "tcp://" + uri + } + } // Overlay our newly mapped configuration onto the autoconf node config that // we generated above. if err = mapstructure.Decode(dat, &cfg); err != nil { From 3ca5f10733fe86241fb185dcac0291bd5d30df94 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 17:52:54 +0000 Subject: [PATCH 3/9] Don't try to correct peers with no schemes in addPeer --- src/yggdrasil/admin.go | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/src/yggdrasil/admin.go b/src/yggdrasil/admin.go index e80ca398..577b6efd 100644 --- a/src/yggdrasil/admin.go +++ b/src/yggdrasil/admin.go @@ -515,13 +515,7 @@ func (a *admin) addPeer(addr string, sintf string) error { return errors.New("invalid peer: " + addr) } } else { - // no url scheme provided - addr = strings.ToLower(addr) - if strings.HasPrefix(addr, "tcp:") { - addr = addr[4:] - } - a.core.tcp.connect(addr, "") - return nil + return errors.New("invalid peer: " + addr) } return nil } From 1a7df477b011aafeb5425c16ee84087128c9fa54 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 17:55:07 +0000 Subject: [PATCH 4/9] Also correct tcp: into tcp:// --- cmd/yggdrasil/main.go | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index ec8c7125..ee5375be 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -196,6 +196,9 @@ func main() { if strings.HasPrefix(uri, "tcp://") || strings.HasPrefix(uri, "socks://") { continue } + if strings.HasPrefix(uri, "tcp:") { + uri = uri[4:] + } (dat["Peers"].([]interface{}))[index] = "tcp://" + uri } // Now do the same with the interface peers @@ -205,6 +208,9 @@ func main() { if strings.HasPrefix(uri, "tcp://") || strings.HasPrefix(uri, "socks://") { continue } + if strings.HasPrefix(uri, "tcp:") { + uri = uri[4:] + } ((dat["InterfacePeers"].(map[string]interface{}))[intf]).([]interface{})[index] = "tcp://" + uri } } From 9eaa2566c1d032d5769574f5825352568374c79f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 18:08:13 +0000 Subject: [PATCH 5/9] Parameterise tun.init --- src/yggdrasil/router.go | 5 +---- src/yggdrasil/tun.go | 4 +++- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index eab18b1e..3b6d2043 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -80,13 +80,10 @@ func (r *router) init(core *Core) { send := make(chan []byte, 32) r.recv = recv r.send = send - r.tun.recv = recv - r.tun.send = send r.reset = make(chan struct{}, 1) r.admin = make(chan func(), 32) r.cryptokey.init(r.core) - r.tun.init(r.core) - // go r.mainLoop() + r.tun.init(r.core, send, recv) } // Starts the mainLoop goroutine. diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index e4625020..85204da5 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -36,9 +36,11 @@ func getSupportedMTU(mtu int) int { } // Initialises the TUN/TAP adapter. -func (tun *tunDevice) init(core *Core) { +func (tun *tunDevice) init(core *Core, send chan<- []byte, recv <-chan []byte) { tun.core = core tun.icmpv6.init(tun) + tun.send = send + tun.recv = recv } // Starts the setup process for the TUN/TAP adapter, and if successful, starts From 2a38ad07cde19d911ff2ee4a41fbb3c346f8f82f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 18:08:40 +0000 Subject: [PATCH 6/9] Don't send ICMPv6 back when tun disabled --- src/yggdrasil/router.go | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index 3b6d2043..d016d1c7 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -270,25 +270,6 @@ func (r *router) sendPacket(bs []byte) { // Drop packets if the session MTU is 0 - this means that one or other // side probably has their TUN adapter disabled if sinfo.getMTU() == 0 { - // Get the size of the oversized payload, up to a max of 900 bytes - window := 900 - if len(bs) < window { - window = len(bs) - } - - // Create the Destination Unreachable response - ptb := &icmp.DstUnreach{ - Data: bs[:window], - } - - // Create the ICMPv6 response from it - icmpv6Buf, err := r.tun.icmpv6.create_icmpv6_tun( - bs[8:24], bs[24:40], - ipv6.ICMPTypeDestinationUnreachable, 1, ptb) - if err == nil { - r.recv <- icmpv6Buf - } - // Don't continue - drop the packet return } From f28360ce4d5d56fe3965bfebe624a0077e53fc6c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 18:10:39 +0000 Subject: [PATCH 7/9] Fix debug builds (foiled by debug builds every time) --- src/yggdrasil/debug.go | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/yggdrasil/debug.go b/src/yggdrasil/debug.go index e463518d..e5bceee0 100644 --- a/src/yggdrasil/debug.go +++ b/src/yggdrasil/debug.go @@ -68,11 +68,11 @@ func (c *Core) DEBUG_getEncryptionPublicKey() boxPubKey { } func (c *Core) DEBUG_getSend() chan<- []byte { - return c.tun.send + return c.router.tun.send } func (c *Core) DEBUG_getRecv() <-chan []byte { - return c.tun.recv + return c.router.tun.recv } // Peer @@ -304,18 +304,18 @@ func (c *Core) DEBUG_startTunWithMTU(ifname string, iftapmode bool, mtu int) { addr := c.DEBUG_getAddr() straddr := fmt.Sprintf("%s/%v", net.IP(addr[:]).String(), 8*len(address_prefix)) if ifname != "none" { - err := c.tun.setup(ifname, iftapmode, straddr, mtu) + err := c.router.tun.setup(ifname, iftapmode, straddr, mtu) if err != nil { panic(err) } - c.log.Println("Setup TUN/TAP:", c.tun.iface.Name(), straddr) - go func() { panic(c.tun.read()) }() + c.log.Println("Setup TUN/TAP:", c.router.tun.iface.Name(), straddr) + go func() { panic(c.router.tun.read()) }() } - go func() { panic(c.tun.write()) }() + go func() { panic(c.router.tun.write()) }() } func (c *Core) DEBUG_stopTun() { - c.tun.close() + c.router.tun.close() } //////////////////////////////////////////////////////////////////////////////// @@ -546,7 +546,7 @@ func DEBUG_simLinkPeers(p, q *peer) { } func (c *Core) DEBUG_simFixMTU() { - c.tun.mtu = 65535 + c.router.tun.mtu = 65535 } //////////////////////////////////////////////////////////////////////////////// From 8045cb4dc3c5e165c848ce0ab4fe7c71bd99d615 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 18:21:08 +0000 Subject: [PATCH 8/9] Define generic adapter type, rename tunDevice to tunAdapter --- src/yggdrasil/icmpv6.go | 4 ++-- src/yggdrasil/router.go | 7 +++++-- src/yggdrasil/tun.go | 16 +++++++--------- src/yggdrasil/tun_bsd.go | 4 ++-- src/yggdrasil/tun_darwin.go | 4 ++-- src/yggdrasil/tun_linux.go | 4 ++-- src/yggdrasil/tun_other.go | 4 ++-- src/yggdrasil/tun_windows.go | 6 +++--- 8 files changed, 25 insertions(+), 24 deletions(-) diff --git a/src/yggdrasil/icmpv6.go b/src/yggdrasil/icmpv6.go index 957b192e..6e9a265b 100644 --- a/src/yggdrasil/icmpv6.go +++ b/src/yggdrasil/icmpv6.go @@ -24,7 +24,7 @@ type macAddress [6]byte const len_ETHER = 14 type icmpv6 struct { - tun *tunDevice + tun *tunAdapter mylladdr net.IP mymac macAddress peermacs map[address]neighbor @@ -57,7 +57,7 @@ func ipv6Header_Marshal(h *ipv6.Header) ([]byte, error) { // Initialises the ICMPv6 module by assigning our link-local IPv6 address and // our MAC address. ICMPv6 messages will always appear to originate from these // addresses. -func (i *icmpv6) init(t *tunDevice) { +func (i *icmpv6) init(t *tunAdapter) { i.tun = t i.peermacs = make(map[address]neighbor) diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index d016d1c7..dd9f05d9 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -31,7 +31,9 @@ import ( ) type adapter struct { - tunDevice + core *Core + send chan<- []byte + recv <-chan []byte } // 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. @@ -43,7 +45,8 @@ 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 tunDevice // TUN/TAP adapter + tun tunAdapter // TUN/TAP adapter + adapters []adapter // Other adapters recv chan<- []byte // place where the tun pulls received packets from send <-chan []byte // place where the tun puts outgoing packets reset chan struct{} // signal that coords changed (re-init sessions/dht) diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index 85204da5..223092e3 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -17,11 +17,9 @@ const tun_IPv6_HEADER_LENGTH = 40 const tun_ETHER_HEADER_LENGTH = 14 // Represents a running TUN/TAP interface. -type tunDevice struct { - core *Core +type tunAdapter struct { + adapter icmpv6 icmpv6 - send chan<- []byte - recv <-chan []byte mtu int iface *water.Interface } @@ -36,7 +34,7 @@ func getSupportedMTU(mtu int) int { } // Initialises the TUN/TAP adapter. -func (tun *tunDevice) init(core *Core, send chan<- []byte, recv <-chan []byte) { +func (tun *tunAdapter) init(core *Core, send chan<- []byte, recv <-chan []byte) { tun.core = core tun.icmpv6.init(tun) tun.send = send @@ -45,7 +43,7 @@ func (tun *tunDevice) init(core *Core, send chan<- []byte, recv <-chan []byte) { // Starts the setup process for the TUN/TAP adapter, and if successful, starts // the read/write goroutines to handle packets on that interface. -func (tun *tunDevice) start(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) start(ifname string, iftapmode bool, addr string, mtu int) error { if ifname == "none" { return nil } @@ -77,7 +75,7 @@ func (tun *tunDevice) start(ifname string, iftapmode bool, addr string, mtu int) // Writes a packet to the TUN/TAP adapter. If the adapter is running in TAP // mode then additional ethernet encapsulation is added for the benefit of the // host operating system. -func (tun *tunDevice) write() error { +func (tun *tunAdapter) write() error { for { data := <-tun.recv if tun.iface == nil { @@ -166,7 +164,7 @@ func (tun *tunDevice) write() error { // is running in TAP mode then the ethernet headers will automatically be // processed and stripped if necessary. If an ICMPv6 packet is found, then // the relevant helper functions in icmpv6.go are called. -func (tun *tunDevice) read() error { +func (tun *tunAdapter) read() error { mtu := tun.mtu if tun.iface.IsTAP() { mtu += tun_ETHER_HEADER_LENGTH @@ -203,7 +201,7 @@ func (tun *tunDevice) read() error { // Closes the TUN/TAP adapter. This is only usually called when the Yggdrasil // process stops. Typically this operation will happen quickly, but on macOS // it can block until a read operation is completed. -func (tun *tunDevice) close() error { +func (tun *tunAdapter) close() error { if tun.iface == nil { return nil } diff --git a/src/yggdrasil/tun_bsd.go b/src/yggdrasil/tun_bsd.go index ca5eaea8..620c79db 100644 --- a/src/yggdrasil/tun_bsd.go +++ b/src/yggdrasil/tun_bsd.go @@ -77,7 +77,7 @@ type in6_ifreq_lifetime struct { // a system socket and making syscalls to the kernel. This is not refined though // and often doesn't work (if at all), therefore if a call fails, it resorts // to calling "ifconfig" instead. -func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { var config water.Config if ifname[:4] == "auto" { ifname = "/dev/tap0" @@ -103,7 +103,7 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) return tun.setupAddress(addr) } -func (tun *tunDevice) setupAddress(addr string) error { +func (tun *tunAdapter) setupAddress(addr string) error { var sfd int var err error diff --git a/src/yggdrasil/tun_darwin.go b/src/yggdrasil/tun_darwin.go index e49ab528..943468e6 100644 --- a/src/yggdrasil/tun_darwin.go +++ b/src/yggdrasil/tun_darwin.go @@ -14,7 +14,7 @@ import ( ) // Configures the "utun" adapter with the correct IPv6 address and MTU. -func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { if iftapmode { tun.core.log.Printf("TAP mode is not supported on this platform, defaulting to TUN") } @@ -62,7 +62,7 @@ type ifreq struct { // Sets the IPv6 address of the utun adapter. On Darwin/macOS this is done using // a system socket and making direct syscalls to the kernel. -func (tun *tunDevice) setupAddress(addr string) error { +func (tun *tunAdapter) setupAddress(addr string) error { var fd int var err error diff --git a/src/yggdrasil/tun_linux.go b/src/yggdrasil/tun_linux.go index aa9e7914..7a7c9cb7 100644 --- a/src/yggdrasil/tun_linux.go +++ b/src/yggdrasil/tun_linux.go @@ -13,7 +13,7 @@ import ( ) // Configures the TAP adapter with the correct IPv6 address and MTU. -func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { var config water.Config if iftapmode { config = water.Config{DeviceType: water.TAP} @@ -48,7 +48,7 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) // is used to do this, so there is not a hard requirement on "ip" or "ifconfig" // to exist on the system, but this will fail if Netlink is not present in the // kernel (it nearly always is). -func (tun *tunDevice) setupAddress(addr string) error { +func (tun *tunAdapter) setupAddress(addr string) error { // Set address var netIF *net.Interface ifces, err := net.Interfaces() diff --git a/src/yggdrasil/tun_other.go b/src/yggdrasil/tun_other.go index 1a3721ac..625f9cd5 100644 --- a/src/yggdrasil/tun_other.go +++ b/src/yggdrasil/tun_other.go @@ -9,7 +9,7 @@ import water "github.com/yggdrasil-network/water" // 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 *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { var config water.Config if iftapmode { config = water.Config{DeviceType: water.TAP} @@ -27,7 +27,7 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) // 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 *tunDevice) setupAddress(addr string) error { +func (tun *tunAdapter) setupAddress(addr string) error { tun.core.log.Println("Platform not supported, you must set the address of", tun.iface.Name(), "to", addr) return nil } diff --git a/src/yggdrasil/tun_windows.go b/src/yggdrasil/tun_windows.go index d3420df8..150a9766 100644 --- a/src/yggdrasil/tun_windows.go +++ b/src/yggdrasil/tun_windows.go @@ -13,7 +13,7 @@ import ( // Configures the TAP adapter with the correct IPv6 address and MTU. On Windows // we don't make use of a direct operating system API to do this - we instead // delegate the hard work to "netsh". -func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) error { +func (tun *tunAdapter) setup(ifname string, iftapmode bool, addr string, mtu int) error { if !iftapmode { tun.core.log.Printf("TUN mode is not supported on this platform, defaulting to TAP") } @@ -65,7 +65,7 @@ func (tun *tunDevice) setup(ifname string, iftapmode bool, addr string, mtu int) } // Sets the MTU of the TAP adapter. -func (tun *tunDevice) setupMTU(mtu int) error { +func (tun *tunAdapter) setupMTU(mtu int) error { // Set MTU cmd := exec.Command("netsh", "interface", "ipv6", "set", "subinterface", fmt.Sprintf("interface=%s", tun.iface.Name()), @@ -82,7 +82,7 @@ func (tun *tunDevice) setupMTU(mtu int) error { } // Sets the IPv6 address of the TAP adapter. -func (tun *tunDevice) setupAddress(addr string) error { +func (tun *tunAdapter) setupAddress(addr string) error { // Set address cmd := exec.Command("netsh", "interface", "ipv6", "add", "address", fmt.Sprintf("interface=%s", tun.iface.Name()), From f9dc300787a3a871144585b813610d6776dd6fc0 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Fri, 14 Dec 2018 18:29:00 +0000 Subject: [PATCH 9/9] Define Adapter base type/interface --- src/yggdrasil/adapter.go | 25 +++++++++++++++++++++++++ src/yggdrasil/router.go | 10 ++-------- src/yggdrasil/tun.go | 6 ++---- 3 files changed, 29 insertions(+), 12 deletions(-) create mode 100644 src/yggdrasil/adapter.go diff --git a/src/yggdrasil/adapter.go b/src/yggdrasil/adapter.go new file mode 100644 index 00000000..4a432092 --- /dev/null +++ b/src/yggdrasil/adapter.go @@ -0,0 +1,25 @@ +package yggdrasil + +// Defines the minimum required functions for an adapter type. +type AdapterInterface interface { + init(core *Core, send chan<- []byte, recv <-chan []byte) + read() error + write() error + close() error +} + +// Defines the minimum required struct members for an adapter type (this is +// now the base type for tunAdapter in tun.go) +type Adapter struct { + AdapterInterface + core *Core + send chan<- []byte + recv <-chan []byte +} + +// Initialises the adapter. +func (adapter *Adapter) init(core *Core, send chan<- []byte, recv <-chan []byte) { + adapter.core = core + adapter.send = send + adapter.recv = recv +} diff --git a/src/yggdrasil/router.go b/src/yggdrasil/router.go index dd9f05d9..62480bc4 100644 --- a/src/yggdrasil/router.go +++ b/src/yggdrasil/router.go @@ -30,12 +30,6 @@ import ( "golang.org/x/net/ipv6" ) -type adapter struct { - core *Core - send chan<- []byte - recv <-chan []byte -} - // 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's mainLoop goroutine is responsible for managing all information related to the dht, searches, and crypto sessions. type router struct { @@ -45,8 +39,8 @@ 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 tunAdapter // TUN/TAP adapter - adapters []adapter // Other adapters + tun tunAdapter // TUN/TAP adapter + adapters []Adapter // Other adapters recv chan<- []byte // place where the tun pulls received packets from send <-chan []byte // place where the tun puts outgoing packets reset chan struct{} // signal that coords changed (re-init sessions/dht) diff --git a/src/yggdrasil/tun.go b/src/yggdrasil/tun.go index 223092e3..26d32c0b 100644 --- a/src/yggdrasil/tun.go +++ b/src/yggdrasil/tun.go @@ -18,7 +18,7 @@ const tun_ETHER_HEADER_LENGTH = 14 // Represents a running TUN/TAP interface. type tunAdapter struct { - adapter + Adapter icmpv6 icmpv6 mtu int iface *water.Interface @@ -35,10 +35,8 @@ func getSupportedMTU(mtu int) int { // Initialises the TUN/TAP adapter. func (tun *tunAdapter) init(core *Core, send chan<- []byte, recv <-chan []byte) { - tun.core = core + tun.Adapter.init(core, send, recv) tun.icmpv6.init(tun) - tun.send = send - tun.recv = recv } // Starts the setup process for the TUN/TAP adapter, and if successful, starts