From f990a56046646ef97322c910b8cd057e99ad035d Mon Sep 17 00:00:00 2001 From: Arceliar Date: Mon, 5 Jul 2021 13:14:12 -0500 Subject: [PATCH 001/334] have the core wrap and export the underlying PacketConn, move IPv6 ReadWriteCloser wrapper logic to a separate package --- cmd/yggdrasil/main.go | 4 +- src/core/api.go | 42 +------ src/core/core.go | 62 ++++++++- src/core/link.go | 2 +- src/core/nodeinfo.go | 4 +- src/core/proto.go | 9 +- src/core/types.go | 7 -- src/{core => ipv6rwc}/icmpv6.go | 2 +- src/{core/keystore.go => ipv6rwc/ipv6rwc.go} | 125 +++++++++++++------ src/tuntap/iface.go | 4 +- src/tuntap/tun.go | 19 ++- 11 files changed, 170 insertions(+), 110 deletions(-) rename src/{core => ipv6rwc}/icmpv6.go (99%) rename src/{core/keystore.go => ipv6rwc/ipv6rwc.go} (77%) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index d6d0d1a6..95d40151 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -29,6 +29,7 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/defaults" "github.com/yggdrasil-network/yggdrasil-go/src/core" + "github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc" "github.com/yggdrasil-network/yggdrasil-go/src/multicast" "github.com/yggdrasil-network/yggdrasil-go/src/tuntap" "github.com/yggdrasil-network/yggdrasil-go/src/version" @@ -353,7 +354,8 @@ func run(args yggArgs, ctx context.Context, done chan struct{}) { } n.multicast.SetupAdminHandlers(n.admin) // Start the TUN/TAP interface - if err := n.tuntap.Init(&n.core, cfg, logger, nil); err != nil { + rwc := ipv6rwc.NewReadWriteCloser(&n.core) + if err := n.tuntap.Init(rwc, cfg, logger, nil); err != nil { logger.Errorln("An error occurred initialising TUN/TAP:", err) } else if err := n.tuntap.Start(); err != nil { logger.Errorln("An error occurred starting TUN/TAP:", err) diff --git a/src/core/api.go b/src/core/api.go index 05d9f36f..6b219340 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -48,7 +48,7 @@ type Session struct { func (c *Core) GetSelf() Self { var self Self - s := c.pc.PacketConn.Debug.GetSelf() + s := c.PacketConn.PacketConn.Debug.GetSelf() self.Key = s.Key self.Root = s.Root self.Coords = s.Coords @@ -63,7 +63,7 @@ func (c *Core) GetPeers() []Peer { names[info.conn] = info.lname } c.links.mutex.Unlock() - ps := c.pc.PacketConn.Debug.GetPeers() + ps := c.PacketConn.PacketConn.Debug.GetPeers() for _, p := range ps { var info Peer info.Key = p.Key @@ -81,7 +81,7 @@ func (c *Core) GetPeers() []Peer { func (c *Core) GetDHT() []DHTEntry { var dhts []DHTEntry - ds := c.pc.PacketConn.Debug.GetDHT() + ds := c.PacketConn.PacketConn.Debug.GetDHT() for _, d := range ds { var info DHTEntry info.Key = d.Key @@ -94,7 +94,7 @@ func (c *Core) GetDHT() []DHTEntry { func (c *Core) GetPaths() []PathEntry { var paths []PathEntry - ps := c.pc.PacketConn.Debug.GetPaths() + ps := c.PacketConn.PacketConn.Debug.GetPaths() for _, p := range ps { var info PathEntry info.Key = p.Key @@ -106,7 +106,7 @@ func (c *Core) GetPaths() []PathEntry { func (c *Core) GetSessions() []Session { var sessions []Session - ss := c.pc.Debug.GetSessions() + ss := c.PacketConn.Debug.GetSessions() for _, s := range ss { var info Session info.Key = s.Key @@ -239,38 +239,6 @@ func (c *Core) PublicKey() ed25519.PublicKey { return c.public } -func (c *Core) MaxMTU() uint64 { - return c.store.maxSessionMTU() -} - -func (c *Core) SetMTU(mtu uint64) { - if mtu < 1280 { - mtu = 1280 - } - c.store.mutex.Lock() - c.store.mtu = mtu - c.store.mutex.Unlock() -} - -func (c *Core) MTU() uint64 { - c.store.mutex.Lock() - mtu := c.store.mtu - c.store.mutex.Unlock() - return mtu -} - -// Implement io.ReadWriteCloser - -func (c *Core) Read(p []byte) (n int, err error) { - n, err = c.store.readPC(p) - return -} - -func (c *Core) Write(p []byte) (n int, err error) { - n, err = c.store.writePC(p) - return -} - func (c *Core) Close() error { c.Stop() return nil diff --git a/src/core/core.go b/src/core/core.go index 89d49177..ac0ea1f0 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -7,10 +7,12 @@ import ( "errors" "fmt" "io/ioutil" + "net" "net/url" "time" - iw "github.com/Arceliar/ironwood/encrypted" + iwe "github.com/Arceliar/ironwood/encrypted" + iwt "github.com/Arceliar/ironwood/types" "github.com/Arceliar/phony" "github.com/gologme/log" @@ -26,13 +28,12 @@ type Core struct { // We're going to keep our own copy of the provided config - that way we can // guarantee that it will be covered by the mutex phony.Inbox - pc *iw.PacketConn + *iwe.PacketConn config *config.NodeConfig // Config secret ed25519.PrivateKey public ed25519.PublicKey links links proto protoHandler - store keyStore log *log.Logger addPeerTimer *time.Timer ctx context.Context @@ -62,9 +63,8 @@ func (c *Core) _init() error { c.public = c.secret.Public().(ed25519.PublicKey) // TODO check public against current.PublicKey, error if they don't match - c.pc, err = iw.NewPacketConn(c.secret) + c.PacketConn, err = iwe.NewPacketConn(c.secret) c.ctx, c.ctxCancel = context.WithCancel(context.Background()) - c.store.init(c) c.proto.init(c) if err := c.proto.nodeinfo.setNodeInfo(c.config.NodeInfo, c.config.NodeInfoPrivacy); err != nil { return fmt.Errorf("setNodeInfo: %w", err) @@ -168,7 +168,7 @@ func (c *Core) Stop() { func (c *Core) _stop() { c.log.Infoln("Stopping...") c.ctxCancel() - c.pc.Close() + c.PacketConn.Close() // TODO make c.Close() do the right thing (act like c.Stop()) if c.addPeerTimer != nil { c.addPeerTimer.Stop() c.addPeerTimer = nil @@ -181,3 +181,53 @@ func (c *Core) _stop() { */ c.log.Infoln("Stopped") } + +func (c *Core) MTU() uint64 { + const sessionTypeOverhead = 1 + return c.PacketConn.MTU() - sessionTypeOverhead +} + +func (c *Core) ReadFrom(p []byte) (n int, from net.Addr, err error) { + buf := make([]byte, c.PacketConn.MTU(), 65535) + for { + bs := buf + n, from, err = c.PacketConn.ReadFrom(bs) + if err != nil { + return 0, from, err + } + if n == 0 { + continue + } + switch bs[0] { + case typeSessionTraffic: + // This is what we want to handle here + case typeSessionProto: + var key keyArray + copy(key[:], from.(iwt.Addr)) + data := append([]byte(nil), bs[1:n]...) + c.proto.handleProto(nil, key, data) + continue + default: + continue + } + bs = bs[1:n] + copy(p, bs) + if len(p) < len(bs) { + n = len(p) + } else { + n = len(bs) + } + return + } +} + +func (c *Core) WriteTo(p []byte, addr net.Addr) (n int, err error) { + buf := make([]byte, 0, 65535) + buf = append(buf, typeSessionTraffic) + buf = append(buf, p...) + n, err = c.PacketConn.WriteTo(buf, addr) + if n > 0 { + n -= 1 + } + return +} diff --git a/src/core/link.go b/src/core/link.go index 165b18b2..ccab9219 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -230,7 +230,7 @@ func (intf *link) handler() (chan struct{}, error) { intf.links.core.log.Infof("Connected %s: %s, source %s", strings.ToUpper(intf.info.linkType), themString, intf.info.local) // Run the handler - err = intf.links.core.pc.HandleConn(ed25519.PublicKey(intf.info.key[:]), intf.conn) + err = intf.links.core.HandleConn(ed25519.PublicKey(intf.info.key[:]), intf.conn) // TODO don't report an error if it's just a 'use of closed network connection' if err != nil { intf.links.core.log.Infof("Disconnected %s: %s, source %s; error: %s", diff --git a/src/core/nodeinfo.go b/src/core/nodeinfo.go index 30644710..90153118 100644 --- a/src/core/nodeinfo.go +++ b/src/core/nodeinfo.go @@ -129,7 +129,7 @@ func (m *nodeinfo) _sendReq(key keyArray, callback func(nodeinfo NodeInfoPayload if callback != nil { m._addCallback(key, callback) } - _, _ = m.proto.core.pc.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:])) + _, _ = m.proto.core.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:])) } func (m *nodeinfo) handleReq(from phony.Actor, key keyArray) { @@ -146,7 +146,7 @@ func (m *nodeinfo) handleRes(from phony.Actor, key keyArray, info NodeInfoPayloa func (m *nodeinfo) _sendRes(key keyArray) { bs := append([]byte{typeSessionProto, typeProtoNodeInfoResponse}, m._getNodeInfo()...) - _, _ = m.proto.core.pc.WriteTo(bs, iwt.Addr(key[:])) + _, _ = m.proto.core.WriteTo(bs, iwt.Addr(key[:])) } // Admin socket stuff diff --git a/src/core/proto.go b/src/core/proto.go index 557ac1d5..f9d12c8a 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -1,6 +1,7 @@ package core import ( + "crypto/ed25519" "encoding/hex" "encoding/json" "errors" @@ -29,6 +30,8 @@ type reqInfo struct { timer *time.Timer // time.AfterFunc cleanup } +type keyArray [ed25519.PublicKeySize]byte + type protoHandler struct { phony.Inbox core *Core @@ -149,7 +152,7 @@ func (p *protoHandler) _handleGetPeersRequest(key keyArray) { for _, pinfo := range peers { tmp := append(bs, pinfo.Key[:]...) const responseOverhead = 2 // 1 debug type, 1 getpeers type - if uint64(len(tmp))+responseOverhead > p.core.store.maxSessionMTU() { + if uint64(len(tmp))+responseOverhead > p.core.MTU() { break } bs = tmp @@ -191,7 +194,7 @@ func (p *protoHandler) _handleGetDHTRequest(key keyArray) { for _, dinfo := range dinfos { tmp := append(bs, dinfo.Key[:]...) const responseOverhead = 2 // 1 debug type, 1 getdht type - if uint64(len(tmp))+responseOverhead > p.core.store.maxSessionMTU() { + if uint64(len(tmp))+responseOverhead > p.core.MTU() { break } bs = tmp @@ -209,7 +212,7 @@ func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) { func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) { bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...) - _, _ = p.core.pc.WriteTo(bs, iwt.Addr(key[:])) + _, _ = p.core.WriteTo(bs, iwt.Addr(key[:])) } // Admin socket stuff diff --git a/src/core/types.go b/src/core/types.go index e325b55e..258563a1 100644 --- a/src/core/types.go +++ b/src/core/types.go @@ -1,12 +1,5 @@ package core -// Out-of-band packet types -const ( - typeKeyDummy = iota // nolint:deadcode,varcheck - typeKeyLookup - typeKeyResponse -) - // In-band packet types const ( typeSessionDummy = iota // nolint:deadcode,varcheck diff --git a/src/core/icmpv6.go b/src/ipv6rwc/icmpv6.go similarity index 99% rename from src/core/icmpv6.go rename to src/ipv6rwc/icmpv6.go index d15fbbcb..8faf1d51 100644 --- a/src/core/icmpv6.go +++ b/src/ipv6rwc/icmpv6.go @@ -1,4 +1,4 @@ -package core +package ipv6rwc // The ICMPv6 module implements functions to easily create ICMPv6 // packets. These functions, when mixed with the built-in Go IPv6 diff --git a/src/core/keystore.go b/src/ipv6rwc/ipv6rwc.go similarity index 77% rename from src/core/keystore.go rename to src/ipv6rwc/ipv6rwc.go index 21fb8459..1c715f0f 100644 --- a/src/core/keystore.go +++ b/src/ipv6rwc/ipv6rwc.go @@ -1,4 +1,4 @@ -package core +package ipv6rwc import ( "crypto/ed25519" @@ -14,14 +14,22 @@ import ( iwt "github.com/Arceliar/ironwood/types" "github.com/yggdrasil-network/yggdrasil-go/src/address" + "github.com/yggdrasil-network/yggdrasil-go/src/core" ) const keyStoreTimeout = 2 * time.Minute +// Out-of-band packet types +const ( + typeKeyDummy = iota // nolint:deadcode,varcheck + typeKeyLookup + typeKeyResponse +) + type keyArray [ed25519.PublicKeySize]byte type keyStore struct { - core *Core + core *core.Core address address.Address subnet address.Subnet mutex sync.Mutex @@ -45,11 +53,11 @@ type buffer struct { timeout *time.Timer } -func (k *keyStore) init(core *Core) { - k.core = core - k.address = *address.AddrForKey(k.core.public) - k.subnet = *address.SubnetForKey(k.core.public) - if err := k.core.pc.SetOutOfBandHandler(k.oobHandler); err != nil { +func (k *keyStore) init(c *core.Core) { + k.core = c + k.address = *address.AddrForKey(k.core.PublicKey()) + k.subnet = *address.SubnetForKey(k.core.PublicKey()) + if err := k.core.SetOutOfBandHandler(k.oobHandler); err != nil { err = fmt.Errorf("tun.core.SetOutOfBandHander: %w", err) panic(err) } @@ -66,7 +74,7 @@ func (k *keyStore) sendToAddress(addr address.Address, bs []byte) { if info := k.addrToInfo[addr]; info != nil { k.resetTimeout(info) k.mutex.Unlock() - _, _ = k.core.pc.WriteTo(bs, iwt.Addr(info.key[:])) + _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) } else { var buf *buffer if buf = k.addrBuffer[addr]; buf == nil { @@ -95,7 +103,7 @@ func (k *keyStore) sendToSubnet(subnet address.Subnet, bs []byte) { if info := k.subnetToInfo[subnet]; info != nil { k.resetTimeout(info) k.mutex.Unlock() - _, _ = k.core.pc.WriteTo(bs, iwt.Addr(info.key[:])) + _, _ = k.core.WriteTo(bs, iwt.Addr(info.key[:])) } else { var buf *buffer if buf = k.subnetBuffer[subnet]; buf == nil { @@ -135,11 +143,11 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.resetTimeout(info) k.mutex.Unlock() if buf := k.addrBuffer[info.address]; buf != nil { - k.core.pc.WriteTo(buf.packet, iwt.Addr(info.key[:])) + k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) delete(k.addrBuffer, info.address) } if buf := k.subnetBuffer[info.subnet]; buf != nil { - k.core.pc.WriteTo(buf.packet, iwt.Addr(info.key[:])) + k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) delete(k.subnetBuffer, info.subnet) } } else { @@ -191,46 +199,29 @@ func (k *keyStore) oobHandler(fromKey, toKey ed25519.PublicKey, data []byte) { } func (k *keyStore) sendKeyLookup(partial ed25519.PublicKey) { - sig := ed25519.Sign(k.core.secret, partial[:]) + sig := ed25519.Sign(k.core.PrivateKey(), partial[:]) bs := append([]byte{typeKeyLookup}, sig...) - _ = k.core.pc.SendOutOfBand(partial, bs) + _ = k.core.SendOutOfBand(partial, bs) } func (k *keyStore) sendKeyResponse(dest ed25519.PublicKey) { - sig := ed25519.Sign(k.core.secret, dest[:]) + sig := ed25519.Sign(k.core.PrivateKey(), dest[:]) bs := append([]byte{typeKeyResponse}, sig...) - _ = k.core.pc.SendOutOfBand(dest, bs) -} - -func (k *keyStore) maxSessionMTU() uint64 { - const sessionTypeOverhead = 1 - return k.core.pc.MTU() - sessionTypeOverhead + _ = k.core.SendOutOfBand(dest, bs) } func (k *keyStore) readPC(p []byte) (int, error) { - buf := make([]byte, k.core.pc.MTU(), 65535) + buf := make([]byte, k.core.MTU(), 65535) for { bs := buf - n, from, err := k.core.pc.ReadFrom(bs) + n, from, err := k.core.ReadFrom(bs) if err != nil { return n, err } if n == 0 { continue } - switch bs[0] { - case typeSessionTraffic: - // This is what we want to handle here - case typeSessionProto: - var key keyArray - copy(key[:], from.(iwt.Addr)) - data := append([]byte(nil), bs[1:n]...) - k.core.proto.handleProto(nil, key, data) - continue - default: - continue - } - bs = bs[1:n] + bs = bs[:n] if len(bs) == 0 { continue } @@ -294,15 +285,69 @@ func (k *keyStore) writePC(bs []byte) (int, error) { strErr := fmt.Sprint("incorrect source address: ", net.IP(srcAddr[:]).String()) return 0, errors.New(strErr) } - buf := make([]byte, 1+len(bs), 65535) - buf[0] = typeSessionTraffic - copy(buf[1:], bs) if dstAddr.IsValid() { - k.sendToAddress(dstAddr, buf) + k.sendToAddress(dstAddr, bs) } else if dstSubnet.IsValid() { - k.sendToSubnet(dstSubnet, buf) + k.sendToSubnet(dstSubnet, bs) } else { return 0, errors.New("invalid destination address") } return len(bs), nil } + +// Exported API + +func (k *keyStore) MaxMTU() uint64 { + return k.core.MTU() +} + +func (k *keyStore) SetMTU(mtu uint64) { + if mtu > k.MaxMTU() { + mtu = k.MaxMTU() + } + if mtu < 1280 { + mtu = 1280 + } + k.mutex.Lock() + k.mtu = mtu + k.mutex.Unlock() +} + +func (k *keyStore) MTU() uint64 { + k.mutex.Lock() + mtu := k.mtu + k.mutex.Unlock() + return mtu +} + +type ReadWriteCloser struct { + keyStore +} + +func NewReadWriteCloser(c *core.Core) *ReadWriteCloser { + rwc := new(ReadWriteCloser) + rwc.init(c) + return rwc +} + +func (rwc *ReadWriteCloser) Address() address.Address { + return rwc.address +} + +func (rwc *ReadWriteCloser) Subnet() address.Subnet { + return rwc.subnet +} + +func (rwc *ReadWriteCloser) Read(p []byte) (n int, err error) { + return rwc.readPC(p) +} + +func (rwc *ReadWriteCloser) Write(p []byte) (n int, err error) { + return rwc.writePC(p) +} + +func (rwc *ReadWriteCloser) Close() error { + err := rwc.core.Close() + rwc.core.Stop() + return err +} diff --git a/src/tuntap/iface.go b/src/tuntap/iface.go index e72b091f..f629399a 100644 --- a/src/tuntap/iface.go +++ b/src/tuntap/iface.go @@ -17,7 +17,7 @@ func (tun *TunAdapter) read() { begin := TUN_OFFSET_BYTES end := begin + n bs := buf[begin:end] - if _, err := tun.core.Write(bs); err != nil { + if _, err := tun.rwc.Write(bs); err != nil { tun.log.Debugln("Unable to send packet:", err) } } @@ -27,7 +27,7 @@ func (tun *TunAdapter) write() { var buf [TUN_OFFSET_BYTES + 65535]byte for { bs := buf[TUN_OFFSET_BYTES:] - n, err := tun.core.Read(bs) + n, err := tun.rwc.Read(bs) if err != nil { tun.log.Errorln("Exiting tun writer due to core read error:", err) return diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index dbba018b..4caefe4a 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -21,8 +21,8 @@ import ( "github.com/yggdrasil-network/yggdrasil-go/src/address" "github.com/yggdrasil-network/yggdrasil-go/src/config" - "github.com/yggdrasil-network/yggdrasil-go/src/core" "github.com/yggdrasil-network/yggdrasil-go/src/defaults" + "github.com/yggdrasil-network/yggdrasil-go/src/ipv6rwc" ) type MTU uint16 @@ -32,7 +32,7 @@ type MTU uint16 // should pass this object to the yggdrasil.SetRouterAdapter() function before // calling yggdrasil.Start(). type TunAdapter struct { - core *core.Core + rwc *ipv6rwc.ReadWriteCloser config *config.NodeConfig log *log.Logger addr address.Address @@ -93,8 +93,8 @@ func MaximumMTU() uint64 { // Init initialises the TUN module. You must have acquired a Listener from // the Yggdrasil core before this point and it must not be in use elsewhere. -func (tun *TunAdapter) Init(core *core.Core, config *config.NodeConfig, log *log.Logger, options interface{}) error { - tun.core = core +func (tun *TunAdapter) Init(rwc *ipv6rwc.ReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { + tun.rwc = rwc tun.config = config tun.log = log return nil @@ -119,9 +119,8 @@ func (tun *TunAdapter) _start() error { if tun.config == nil { return errors.New("no configuration available to TUN") } - pk := tun.core.PublicKey() - tun.addr = *address.AddrForKey(pk) - tun.subnet = *address.SubnetForKey(pk) + tun.addr = tun.rwc.Address() + tun.subnet = tun.rwc.Subnet() addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1) if tun.config.IfName == "none" || tun.config.IfName == "dummy" { tun.log.Debugln("Not starting TUN as ifname is none or dummy") @@ -130,8 +129,8 @@ func (tun *TunAdapter) _start() error { return nil } mtu := tun.config.IfMTU - if tun.core.MaxMTU() < mtu { - mtu = tun.core.MaxMTU() + if tun.rwc.MaxMTU() < mtu { + mtu = tun.rwc.MaxMTU() } if err := tun.setup(tun.config.IfName, addr, mtu); err != nil { return err @@ -139,7 +138,7 @@ func (tun *TunAdapter) _start() error { if tun.MTU() != mtu { tun.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", tun.config.IfMTU, tun.MTU(), MaximumMTU()) } - tun.core.SetMTU(tun.MTU()) + tun.rwc.SetMTU(tun.MTU()) tun.isOpen = true tun.isEnabled = true go tun.read() From e4ce2c79a9a6430f7145798a9a3e93c544bd869c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 5 Jul 2021 22:26:09 +0100 Subject: [PATCH 002/334] Add LocalAddr to complete net.PacketConn interface --- src/core/core.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/core/core.go b/src/core/core.go index ac0ea1f0..8c816d2b 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -231,3 +231,7 @@ func (c *Core) WriteTo(p []byte, addr net.Addr) (n int, err error) { } return } + +func (c *Core) LocalAddr() net.Addr { + return iwt.Addr(c.public) +} From e224c02d6d88cfd36a0f8598dccfd4cbd4e1f297 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 5 Jul 2021 22:35:46 +0100 Subject: [PATCH 003/334] Revert "Add LocalAddr to complete net.PacketConn interface" This reverts commit e4ce2c79a9a6430f7145798a9a3e93c544bd869c. --- src/core/core.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/core/core.go b/src/core/core.go index 8c816d2b..ac0ea1f0 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -231,7 +231,3 @@ func (c *Core) WriteTo(p []byte, addr net.Addr) (n int, err error) { } return } - -func (c *Core) LocalAddr() net.Addr { - return iwt.Addr(c.public) -} From 3704ebf4cbeab2b5818ca545e0bebfce2c7bd10a Mon Sep 17 00:00:00 2001 From: Arceliar Date: Tue, 6 Jul 2021 19:45:12 -0500 Subject: [PATCH 004/334] fix debug rpcs and cleanup core.Close/core.Stop --- src/core/api.go | 5 ----- src/core/core.go | 26 ++++++++++++++++---------- src/core/nodeinfo.go | 4 ++-- src/core/proto.go | 2 +- 4 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/core/api.go b/src/core/api.go index 6b219340..c312923d 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -239,11 +239,6 @@ func (c *Core) PublicKey() ed25519.PublicKey { return c.public } -func (c *Core) Close() error { - c.Stop() - return nil -} - // Hack to get the admin stuff working, TODO something cleaner type AddHandler interface { diff --git a/src/core/core.go b/src/core/core.go index ac0ea1f0..0332980b 100644 --- a/src/core/core.go +++ b/src/core/core.go @@ -161,25 +161,31 @@ func (c *Core) _start(nc *config.NodeConfig, log *log.Logger) error { // Stop shuts down the Yggdrasil node. func (c *Core) Stop() { - phony.Block(c, c._stop) + phony.Block(c, func() { + c.log.Infoln("Stopping...") + c._close() + c.log.Infoln("Stopped") + }) +} + +func (c *Core) Close() error { + var err error + phony.Block(c, func() { + err = c._close() + }) + return err } // This function is unsafe and should only be ran by the core actor. -func (c *Core) _stop() { - c.log.Infoln("Stopping...") +func (c *Core) _close() error { c.ctxCancel() - c.PacketConn.Close() // TODO make c.Close() do the right thing (act like c.Stop()) + err := c.PacketConn.Close() if c.addPeerTimer != nil { c.addPeerTimer.Stop() c.addPeerTimer = nil } _ = c.links.stop() - /* FIXME this deadlocks, need a waitgroup or something to coordinate shutdown - for _, peer := range c.GetPeers() { - c.DisconnectPeer(peer.Port) - } - */ - c.log.Infoln("Stopped") + return err } func (c *Core) MTU() uint64 { diff --git a/src/core/nodeinfo.go b/src/core/nodeinfo.go index 90153118..4ca21d73 100644 --- a/src/core/nodeinfo.go +++ b/src/core/nodeinfo.go @@ -129,7 +129,7 @@ func (m *nodeinfo) _sendReq(key keyArray, callback func(nodeinfo NodeInfoPayload if callback != nil { m._addCallback(key, callback) } - _, _ = m.proto.core.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:])) + _, _ = m.proto.core.PacketConn.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:])) } func (m *nodeinfo) handleReq(from phony.Actor, key keyArray) { @@ -146,7 +146,7 @@ func (m *nodeinfo) handleRes(from phony.Actor, key keyArray, info NodeInfoPayloa func (m *nodeinfo) _sendRes(key keyArray) { bs := append([]byte{typeSessionProto, typeProtoNodeInfoResponse}, m._getNodeInfo()...) - _, _ = m.proto.core.WriteTo(bs, iwt.Addr(key[:])) + _, _ = m.proto.core.PacketConn.WriteTo(bs, iwt.Addr(key[:])) } // Admin socket stuff diff --git a/src/core/proto.go b/src/core/proto.go index f9d12c8a..e60caeff 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -212,7 +212,7 @@ func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) { func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) { bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...) - _, _ = p.core.WriteTo(bs, iwt.Addr(key[:])) + _, _ = p.core.PacketConn.WriteTo(bs, iwt.Addr(key[:])) } // Admin socket stuff From cd5383f7b799932b2536e4ee82e768558a073ec5 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Wed, 7 Jul 2021 18:36:51 -0500 Subject: [PATCH 005/334] fix core tests --- src/core/core_test.go | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/core_test.go b/src/core/core_test.go index dd60af21..fcfe2e31 100644 --- a/src/core/core_test.go +++ b/src/core/core_test.go @@ -44,13 +44,11 @@ func CreateAndConnectTwo(t testing.TB, verbose bool) (nodeA *Core, nodeB *Core) if err := nodeA.Start(GenerateConfig(), GetLoggerWithPrefix("A: ", verbose)); err != nil { t.Fatal(err) } - nodeA.SetMTU(1500) nodeB = new(Core) if err := nodeB.Start(GenerateConfig(), GetLoggerWithPrefix("B: ", verbose)); err != nil { t.Fatal(err) } - nodeB.SetMTU(1500) u, err := url.Parse("tcp://" + nodeA.links.tcp.getAddr().String()) if err != nil { @@ -94,7 +92,7 @@ func CreateEchoListener(t testing.TB, nodeA *Core, bufLen int, repeats int) chan buf := make([]byte, bufLen) res := make([]byte, bufLen) for i := 0; i < repeats; i++ { - n, err := nodeA.Read(buf) + n, from, err := nodeA.ReadFrom(buf) if err != nil { t.Error(err) return @@ -106,7 +104,7 @@ func CreateEchoListener(t testing.TB, nodeA *Core, bufLen int, repeats int) chan copy(res, buf) copy(res[8:24], buf[24:40]) copy(res[24:40], buf[8:24]) - _, err = nodeA.Write(res) + _, err = nodeA.WriteTo(res, from) if err != nil { t.Error(err) } @@ -141,12 +139,12 @@ func TestCore_Start_Transfer(t *testing.T) { msg[0] = 0x60 copy(msg[8:24], nodeB.Address()) copy(msg[24:40], nodeA.Address()) - _, err := nodeB.Write(msg) + _, err := nodeB.WriteTo(msg, nodeA.LocalAddr()) if err != nil { t.Fatal(err) } buf := make([]byte, msgLen) - _, err = nodeB.Read(buf) + _, _, err = nodeB.ReadFrom(buf) if err != nil { t.Fatal(err) } @@ -179,12 +177,13 @@ func BenchmarkCore_Start_Transfer(b *testing.B) { b.SetBytes(int64(msgLen)) b.ResetTimer() + addr := nodeA.LocalAddr() for i := 0; i < b.N; i++ { - _, err := nodeB.Write(msg) + _, err := nodeB.WriteTo(msg, addr) if err != nil { b.Fatal(err) } - _, err = nodeB.Read(buf) + _, _, err = nodeB.ReadFrom(buf) if err != nil { b.Fatal(err) } From 04ecdf60453846e0ab397f1a36497bb3b268f2bb Mon Sep 17 00:00:00 2001 From: Timur Demin Date: Tue, 6 Jul 2021 21:24:21 +0500 Subject: [PATCH 006/334] Preallocate memory when deriving address from key This makes src/address.AddrForKey preallocate 32 bytes before starting the address derivation. As benches in syg_go show, reallocating temp takes 20% of the function runtime. --- src/address/address.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/address/address.go b/src/address/address.go index 7add23ac..0e2400ed 100644 --- a/src/address/address.go +++ b/src/address/address.go @@ -64,7 +64,7 @@ func AddrForKey(publicKey ed25519.PublicKey) *Address { buf[idx] = ^buf[idx] } var addr Address - var temp []byte + var temp = make([]byte, 0, 32) done := false ones := byte(0) bits := byte(0) From 6a0ddc20efb5d5e79cc64630d3fdeddb8101149f Mon Sep 17 00:00:00 2001 From: cofob <49928332+cofob@users.noreply.github.com> Date: Wed, 21 Jul 2021 17:57:59 +0700 Subject: [PATCH 007/334] Allow yggdrasil bind to ports <1024 --- contrib/systemd/yggdrasil.service | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/contrib/systemd/yggdrasil.service b/contrib/systemd/yggdrasil.service index 3002e61b..27d27907 100644 --- a/contrib/systemd/yggdrasil.service +++ b/contrib/systemd/yggdrasil.service @@ -10,7 +10,7 @@ Group=yggdrasil ProtectHome=true ProtectSystem=true SyslogIdentifier=yggdrasil -CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW +CapabilityBoundingSet=CAP_NET_ADMIN CAP_NET_RAW CAP_NET_BIND_SERVICE ExecStartPre=+-/sbin/modprobe tun ExecStart=/usr/bin/yggdrasil -useconffile /etc/yggdrasil.conf ExecReload=/bin/kill -HUP $MAINPID From d8df9755f2e8c41ee21110f77bc0b0b662f59414 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 22:11:20 +0100 Subject: [PATCH 008/334] Allow specifying TLS SNI with ?sni= in peering URI --- src/core/link.go | 1 + src/core/tcp.go | 1 + src/core/tls.go | 13 ++++++++----- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index ccab9219..f753156e 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -98,6 +98,7 @@ func (l *links) call(u *url.URL, sintf string) error { l.tcp.call(pathtokens[0], tcpOpts, sintf) case "tls": tcpOpts.upgrade = l.tcp.tls.forDialer + tcpOpts.tlsSNI = u.Query().Get("sni") l.tcp.call(u.Host, tcpOpts, sintf) default: return errors.New("unknown call scheme: " + u.Scheme) diff --git a/src/core/tcp.go b/src/core/tcp.go index 572fd652..7b1773b8 100644 --- a/src/core/tcp.go +++ b/src/core/tcp.go @@ -64,6 +64,7 @@ type tcpOptions struct { socksProxyAddr string socksProxyAuth *proxy.Auth socksPeerAddr string + tlsSNI string } func (l *TcpListener) Stop() { diff --git a/src/core/tls.go b/src/core/tls.go index 4c25225b..eb21fcbc 100644 --- a/src/core/tls.go +++ b/src/core/tls.go @@ -77,8 +77,8 @@ func (t *tcptls) init(tcp *tcp) { } } -func (t *tcptls) configForOptions(options *tcpOptions) *tls.Config { - config := *t.config +func (t *tcptls) configForOptions(options *tcpOptions, serverName string) *tls.Config { + config := t.config.Clone() config.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { if len(rawCerts) != 1 { return errors.New("tls not exactly 1 cert") @@ -103,11 +103,14 @@ func (t *tcptls) configForOptions(options *tcpOptions) *tls.Config { } return nil } - return &config + if serverName != "" { + config.ServerName = serverName + } + return config } func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options) + config := t.configForOptions(options, "") conn := tls.Server(c, config) if err := conn.Handshake(); err != nil { return c, err @@ -116,7 +119,7 @@ func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, err } func (t *tcptls) upgradeDialer(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options) + config := t.configForOptions(options, options.tlsSNI) conn := tls.Client(c, config) if err := conn.Handshake(); err != nil { return c, err From f094cf34bf23bde6d6c8515c79f1ad14ea3a230c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 28 Jul 2021 22:23:33 +0100 Subject: [PATCH 009/334] Set SNI by default if the peering URI contains a DNS name --- src/core/link.go | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/core/link.go b/src/core/link.go index f753156e..98a7ab31 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -99,6 +99,13 @@ func (l *links) call(u *url.URL, sintf string) error { case "tls": tcpOpts.upgrade = l.tcp.tls.forDialer tcpOpts.tlsSNI = u.Query().Get("sni") + if tcpOpts.tlsSNI == "" { + // SNI headers must contain hostnames and not IP addresses, so we must make sure + // that we do not populate the SNI with an IP literal. + if host, _, err := net.SplitHostPort(u.Host); err == nil && net.ParseIP(host) == nil { + tcpOpts.tlsSNI = host + } + } l.tcp.call(u.Host, tcpOpts, sintf) default: return errors.New("unknown call scheme: " + u.Scheme) From bbdff033ce29d657c099f73f7946c1d5061a1b9c Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 1 Aug 2021 21:36:51 +0100 Subject: [PATCH 010/334] Update SNI code --- src/core/link.go | 14 +++++++++++--- src/core/tls.go | 10 ++++------ 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 98a7ab31..755d38a3 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -98,10 +98,18 @@ func (l *links) call(u *url.URL, sintf string) error { l.tcp.call(pathtokens[0], tcpOpts, sintf) case "tls": tcpOpts.upgrade = l.tcp.tls.forDialer - tcpOpts.tlsSNI = u.Query().Get("sni") + // SNI headers must contain hostnames and not IP addresses, so we must make sure + // that we do not populate the SNI with an IP literal. We do this by splitting + // the host-port combo from the query option and then seeing if it parses to an + // IP address successfully or not. + if sni := u.Query().Get("sni"); sni != "" { + if host, _, err := net.SplitHostPort(sni); err == nil && net.ParseIP(host) == nil { + tcpOpts.tlsSNI = host + } + } + // If the SNI is not configured still because the above failed then we'll try + // again but this time we'll use the host part of the peering URI instead. if tcpOpts.tlsSNI == "" { - // SNI headers must contain hostnames and not IP addresses, so we must make sure - // that we do not populate the SNI with an IP literal. if host, _, err := net.SplitHostPort(u.Host); err == nil && net.ParseIP(host) == nil { tcpOpts.tlsSNI = host } diff --git a/src/core/tls.go b/src/core/tls.go index eb21fcbc..9e340ac4 100644 --- a/src/core/tls.go +++ b/src/core/tls.go @@ -77,7 +77,7 @@ func (t *tcptls) init(tcp *tcp) { } } -func (t *tcptls) configForOptions(options *tcpOptions, serverName string) *tls.Config { +func (t *tcptls) configForOptions(options *tcpOptions) *tls.Config { config := t.config.Clone() config.VerifyPeerCertificate = func(rawCerts [][]byte, _ [][]*x509.Certificate) error { if len(rawCerts) != 1 { @@ -103,14 +103,11 @@ func (t *tcptls) configForOptions(options *tcpOptions, serverName string) *tls.C } return nil } - if serverName != "" { - config.ServerName = serverName - } return config } func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options, "") + config := t.configForOptions(options) conn := tls.Server(c, config) if err := conn.Handshake(); err != nil { return c, err @@ -119,7 +116,8 @@ func (t *tcptls) upgradeListener(c net.Conn, options *tcpOptions) (net.Conn, err } func (t *tcptls) upgradeDialer(c net.Conn, options *tcpOptions) (net.Conn, error) { - config := t.configForOptions(options, options.tlsSNI) + config := t.configForOptions(options) + config.ServerName = options.tlsSNI conn := tls.Client(c, config) if err := conn.Handshake(); err != nil { return c, err From d1cd671bece1c69942f069d059174f01d5565406 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sun, 1 Aug 2021 21:39:49 +0100 Subject: [PATCH 011/334] Fix bug --- src/core/link.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/link.go b/src/core/link.go index 755d38a3..8797b886 100644 --- a/src/core/link.go +++ b/src/core/link.go @@ -103,8 +103,8 @@ func (l *links) call(u *url.URL, sintf string) error { // the host-port combo from the query option and then seeing if it parses to an // IP address successfully or not. if sni := u.Query().Get("sni"); sni != "" { - if host, _, err := net.SplitHostPort(sni); err == nil && net.ParseIP(host) == nil { - tcpOpts.tlsSNI = host + if net.ParseIP(sni) == nil { + tcpOpts.tlsSNI = sni } } // If the SNI is not configured still because the above failed then we'll try From cbb6dc1b7d16616a27b31befcc5a9cf2b08b62c2 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Tue, 3 Aug 2021 02:47:38 +0500 Subject: [PATCH 012/334] Split yggdrasilctl code into separate functions (refactoring) (#815) * Move yggdrasilctl responses to separate functions * Move yggdrasilctl request switch to separate function * Add empty lines * Create struct CmdLine for yggdrasilctl * Move yggdrasilctl command line parsing to separate func * Turn struct CmdLine into CmdLineEnv * Rename func parseCmdLine to parseFlagsAndArgs * Move yggdrasilctl endpoint setting logic into separate func * Function to create yggdrasilctl CmdLineEnv * Reorder code * Move struct fields into lines * Turn yggdrasilctl CmdLineEnv funcs to methods * Move yggdrasilctl connection code to separate func * Rename functions * Move yggdrasilctl command line env to separate mod * Move yggdrasilctl command line env to main mod * Run goimports Co-authored-by: Neil Alexander --- cmd/yggdrasilctl/cmd_line_env.go | 94 +++++ cmd/yggdrasilctl/main.go | 651 ++++++++++++++++--------------- 2 files changed, 422 insertions(+), 323 deletions(-) create mode 100644 cmd/yggdrasilctl/cmd_line_env.go diff --git a/cmd/yggdrasilctl/cmd_line_env.go b/cmd/yggdrasilctl/cmd_line_env.go new file mode 100644 index 00000000..bd6df8fc --- /dev/null +++ b/cmd/yggdrasilctl/cmd_line_env.go @@ -0,0 +1,94 @@ +package main + +import ( + "bytes" + "flag" + "fmt" + "io/ioutil" + "log" + "os" + + "github.com/hjson/hjson-go" + "golang.org/x/text/encoding/unicode" + + "github.com/yggdrasil-network/yggdrasil-go/src/defaults" +) + +type CmdLineEnv struct { + args []string + endpoint, server string + injson, verbose, ver bool +} + +func newCmdLineEnv() CmdLineEnv { + var cmdLineEnv CmdLineEnv + cmdLineEnv.endpoint = defaults.GetDefaults().DefaultAdminListen + return cmdLineEnv +} + +func (cmdLineEnv *CmdLineEnv) parseFlagsAndArgs() { + flag.Usage = func() { + fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n\n", os.Args[0]) + fmt.Println("Options:") + flag.PrintDefaults() + fmt.Println() + fmt.Println("Please note that options must always specified BEFORE the command\non the command line or they will be ignored.") + fmt.Println() + fmt.Println("Commands:\n - Use \"list\" for a list of available commands") + fmt.Println() + fmt.Println("Examples:") + fmt.Println(" - ", os.Args[0], "list") + fmt.Println(" - ", os.Args[0], "getPeers") + fmt.Println(" - ", os.Args[0], "-v getSelf") + fmt.Println(" - ", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") + fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") + fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") + } + + server := flag.String("endpoint", cmdLineEnv.endpoint, "Admin socket endpoint") + injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") + verbose := flag.Bool("v", false, "Verbose output (includes public keys)") + ver := flag.Bool("version", false, "Prints the version of this build") + + flag.Parse() + + cmdLineEnv.args = flag.Args() + cmdLineEnv.server = *server + cmdLineEnv.injson = *injson + cmdLineEnv.verbose = *verbose + cmdLineEnv.ver = *ver +} + +func (cmdLineEnv *CmdLineEnv) setEndpoint(logger *log.Logger) { + if cmdLineEnv.server == cmdLineEnv.endpoint { + if config, err := ioutil.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil { + if bytes.Equal(config[0:2], []byte{0xFF, 0xFE}) || + bytes.Equal(config[0:2], []byte{0xFE, 0xFF}) { + utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM) + decoder := utf.NewDecoder() + config, err = decoder.Bytes(config) + if err != nil { + panic(err) + } + } + var dat map[string]interface{} + if err := hjson.Unmarshal(config, &dat); err != nil { + panic(err) + } + if ep, ok := dat["AdminListen"].(string); ok && (ep != "none" && ep != "") { + cmdLineEnv.endpoint = ep + logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Using endpoint", cmdLineEnv.endpoint, "from AdminListen") + } else { + logger.Println("Configuration file doesn't contain appropriate AdminListen option") + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + } + } else { + logger.Println("Can't open config file from default location", defaults.GetDefaults().DefaultConfigFile) + logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) + } + } else { + cmdLineEnv.endpoint = cmdLineEnv.server + logger.Println("Using endpoint", cmdLineEnv.endpoint, "from command line") + } +} diff --git a/cmd/yggdrasilctl/main.go b/cmd/yggdrasilctl/main.go index 91923392..788b4f19 100644 --- a/cmd/yggdrasilctl/main.go +++ b/cmd/yggdrasilctl/main.go @@ -6,7 +6,6 @@ import ( "errors" "flag" "fmt" - "io/ioutil" "log" "net" "net/url" @@ -15,10 +14,6 @@ import ( "strconv" "strings" - "golang.org/x/text/encoding/unicode" - - "github.com/hjson/hjson-go" - "github.com/yggdrasil-network/yggdrasil-go/src/defaults" "github.com/yggdrasil-network/yggdrasil-go/src/version" ) @@ -32,6 +27,7 @@ func main() { func run() int { logbuffer := &bytes.Buffer{} logger := log.New(logbuffer, "", log.Flags()) + defer func() int { if r := recover(); r != nil { logger.Println("Fatal error:", r) @@ -41,97 +37,24 @@ func run() int { return 0 }() - endpoint := defaults.GetDefaults().DefaultAdminListen + cmdLineEnv := newCmdLineEnv() + cmdLineEnv.parseFlagsAndArgs() - flag.Usage = func() { - fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n\n", os.Args[0]) - fmt.Println("Options:") - flag.PrintDefaults() - fmt.Println() - fmt.Println("Please note that options must always specified BEFORE the command\non the command line or they will be ignored.") - fmt.Println() - fmt.Println("Commands:\n - Use \"list\" for a list of available commands") - fmt.Println() - fmt.Println("Examples:") - fmt.Println(" - ", os.Args[0], "list") - fmt.Println(" - ", os.Args[0], "getPeers") - fmt.Println(" - ", os.Args[0], "-v getSelf") - fmt.Println(" - ", os.Args[0], "setTunTap name=auto mtu=1500 tap_mode=false") - fmt.Println(" - ", os.Args[0], "-endpoint=tcp://localhost:9001 getDHT") - fmt.Println(" - ", os.Args[0], "-endpoint=unix:///var/run/ygg.sock getDHT") - } - server := flag.String("endpoint", endpoint, "Admin socket endpoint") - injson := flag.Bool("json", false, "Output in JSON format (as opposed to pretty-print)") - verbose := flag.Bool("v", false, "Verbose output (includes public keys)") - ver := flag.Bool("version", false, "Prints the version of this build") - flag.Parse() - args := flag.Args() - - if *ver { + if cmdLineEnv.ver { fmt.Println("Build name:", version.BuildName()) fmt.Println("Build version:", version.BuildVersion()) fmt.Println("To get the version number of the running Yggdrasil node, run", os.Args[0], "getSelf") return 0 } - if len(args) == 0 { + if len(cmdLineEnv.args) == 0 { flag.Usage() return 0 } - if *server == endpoint { - if config, err := ioutil.ReadFile(defaults.GetDefaults().DefaultConfigFile); err == nil { - if bytes.Equal(config[0:2], []byte{0xFF, 0xFE}) || - bytes.Equal(config[0:2], []byte{0xFE, 0xFF}) { - utf := unicode.UTF16(unicode.BigEndian, unicode.UseBOM) - decoder := utf.NewDecoder() - config, err = decoder.Bytes(config) - if err != nil { - panic(err) - } - } - var dat map[string]interface{} - if err := hjson.Unmarshal(config, &dat); err != nil { - panic(err) - } - if ep, ok := dat["AdminListen"].(string); ok && (ep != "none" && ep != "") { - endpoint = ep - logger.Println("Found platform default config file", defaults.GetDefaults().DefaultConfigFile) - logger.Println("Using endpoint", endpoint, "from AdminListen") - } else { - logger.Println("Configuration file doesn't contain appropriate AdminListen option") - logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) - } - } else { - logger.Println("Can't open config file from default location", defaults.GetDefaults().DefaultConfigFile) - logger.Println("Falling back to platform default", defaults.GetDefaults().DefaultAdminListen) - } - } else { - endpoint = *server - logger.Println("Using endpoint", endpoint, "from command line") - } + cmdLineEnv.setEndpoint(logger) - var conn net.Conn - u, err := url.Parse(endpoint) - if err == nil { - switch strings.ToLower(u.Scheme) { - case "unix": - logger.Println("Connecting to UNIX socket", endpoint[7:]) - conn, err = net.Dial("unix", endpoint[7:]) - case "tcp": - logger.Println("Connecting to TCP socket", u.Host) - conn, err = net.Dial("tcp", u.Host) - default: - logger.Println("Unknown protocol or malformed address - check your endpoint") - err = errors.New("protocol not supported") - } - } else { - logger.Println("Connecting to TCP socket", u.Host) - conn, err = net.Dial("tcp", endpoint) - } - if err != nil { - panic(err) - } + conn := connect(cmdLineEnv.endpoint, logger) logger.Println("Connected") defer conn.Close() @@ -140,7 +63,7 @@ func run() int { send := make(admin_info) recv := make(admin_info) - for c, a := range args { + for c, a := range cmdLineEnv.args { if c == 0 { if strings.HasPrefix(a, "-") { logger.Printf("Ignoring flag %s as it should be specified before other parameters\n", a) @@ -176,7 +99,9 @@ func run() int { if err := encoder.Encode(&send); err != nil { panic(err) } + logger.Printf("Request sent") + if err := decoder.Decode(&recv); err == nil { logger.Printf("Response received") if recv["status"] == "error" { @@ -195,252 +120,16 @@ func run() int { fmt.Println("Missing response body (malformed response?)") return 1 } - req := recv["request"].(map[string]interface{}) res := recv["response"].(map[string]interface{}) - if *injson { + if cmdLineEnv.injson { if json, err := json.MarshalIndent(res, "", " "); err == nil { fmt.Println(string(json)) } return 0 } - switch strings.ToLower(req["request"].(string)) { - case "dot": - fmt.Println(res["dot"]) - case "list", "getpeers", "getswitchpeers", "getdht", "getsessions", "dhtping": - maxWidths := make(map[string]int) - var keyOrder []string - keysOrdered := false - - for _, tlv := range res { - for slk, slv := range tlv.(map[string]interface{}) { - if !keysOrdered { - for k := range slv.(map[string]interface{}) { - if !*verbose { - if k == "box_pub_key" || k == "box_sig_key" || k == "nodeinfo" || k == "was_mtu_fixed" { - continue - } - } - keyOrder = append(keyOrder, fmt.Sprint(k)) - } - sort.Strings(keyOrder) - keysOrdered = true - } - for k, v := range slv.(map[string]interface{}) { - if len(fmt.Sprint(slk)) > maxWidths["key"] { - maxWidths["key"] = len(fmt.Sprint(slk)) - } - if len(fmt.Sprint(v)) > maxWidths[k] { - maxWidths[k] = len(fmt.Sprint(v)) - if maxWidths[k] < len(k) { - maxWidths[k] = len(k) - } - } - } - } - - if len(keyOrder) > 0 { - fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s ", "") - for _, v := range keyOrder { - fmt.Printf("%-"+fmt.Sprint(maxWidths[v])+"s ", v) - } - fmt.Println() - } - - for slk, slv := range tlv.(map[string]interface{}) { - fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s ", slk) - for _, k := range keyOrder { - preformatted := slv.(map[string]interface{})[k] - var formatted string - switch k { - case "bytes_sent", "bytes_recvd": - formatted = fmt.Sprintf("%d", uint(preformatted.(float64))) - case "uptime", "last_seen": - seconds := uint(preformatted.(float64)) % 60 - minutes := uint(preformatted.(float64)/60) % 60 - hours := uint(preformatted.(float64) / 60 / 60) - formatted = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) - default: - formatted = fmt.Sprint(preformatted) - } - fmt.Printf("%-"+fmt.Sprint(maxWidths[k])+"s ", formatted) - } - fmt.Println() - } - } - case "gettuntap", "settuntap": - for k, v := range res { - fmt.Println("Interface name:", k) - if mtu, ok := v.(map[string]interface{})["mtu"].(float64); ok { - fmt.Println("Interface MTU:", mtu) - } - if tap_mode, ok := v.(map[string]interface{})["tap_mode"].(bool); ok { - fmt.Println("TAP mode:", tap_mode) - } - } - case "getself": - for k, v := range res["self"].(map[string]interface{}) { - if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok && buildname != "unknown" { - fmt.Println("Build name:", buildname) - } - if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" { - fmt.Println("Build version:", buildversion) - } - fmt.Println("IPv6 address:", k) - if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok { - fmt.Println("IPv6 subnet:", subnet) - } - if boxSigKey, ok := v.(map[string]interface{})["key"].(string); ok { - fmt.Println("Public key:", boxSigKey) - } - if coords, ok := v.(map[string]interface{})["coords"].(string); ok { - fmt.Println("Coords:", coords) - } - if *verbose { - if nodeID, ok := v.(map[string]interface{})["node_id"].(string); ok { - fmt.Println("Node ID:", nodeID) - } - if boxPubKey, ok := v.(map[string]interface{})["box_pub_key"].(string); ok { - fmt.Println("Public encryption key:", boxPubKey) - } - if boxSigKey, ok := v.(map[string]interface{})["box_sig_key"].(string); ok { - fmt.Println("Public signing key:", boxSigKey) - } - } - } - case "getswitchqueues": - maximumqueuesize := float64(4194304) - portqueues := make(map[float64]float64) - portqueuesize := make(map[float64]float64) - portqueuepackets := make(map[float64]float64) - v := res["switchqueues"].(map[string]interface{}) - if queuecount, ok := v["queues_count"].(float64); ok { - fmt.Printf("Active queue count: %d queues\n", uint(queuecount)) - } - if queuesize, ok := v["queues_size"].(float64); ok { - fmt.Printf("Active queue size: %d bytes\n", uint(queuesize)) - } - if highestqueuecount, ok := v["highest_queues_count"].(float64); ok { - fmt.Printf("Highest queue count: %d queues\n", uint(highestqueuecount)) - } - if highestqueuesize, ok := v["highest_queues_size"].(float64); ok { - fmt.Printf("Highest queue size: %d bytes\n", uint(highestqueuesize)) - } - if m, ok := v["maximum_queues_size"].(float64); ok { - maximumqueuesize = m - fmt.Printf("Maximum queue size: %d bytes\n", uint(maximumqueuesize)) - } - if queues, ok := v["queues"].([]interface{}); ok { - if len(queues) != 0 { - fmt.Println("Active queues:") - for _, v := range queues { - queueport := v.(map[string]interface{})["queue_port"].(float64) - queuesize := v.(map[string]interface{})["queue_size"].(float64) - queuepackets := v.(map[string]interface{})["queue_packets"].(float64) - queueid := v.(map[string]interface{})["queue_id"].(string) - portqueues[queueport]++ - portqueuesize[queueport] += queuesize - portqueuepackets[queueport] += queuepackets - queuesizepercent := (100 / maximumqueuesize) * queuesize - fmt.Printf("- Switch port %d, Stream ID: %v, size: %d bytes (%d%% full), %d packets\n", - uint(queueport), []byte(queueid), uint(queuesize), - uint(queuesizepercent), uint(queuepackets)) - } - } - } - if len(portqueuesize) > 0 && len(portqueuepackets) > 0 { - fmt.Println("Aggregated statistics by switchport:") - for k, v := range portqueuesize { - queuesizepercent := (100 / (portqueues[k] * maximumqueuesize)) * v - fmt.Printf("- Switch port %d, size: %d bytes (%d%% full), %d packets\n", - uint(k), uint(v), uint(queuesizepercent), uint(portqueuepackets[k])) - } - } - case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey", "addsourcesubnet", "addroute", "removesourcesubnet", "removeroute": - if _, ok := res["added"]; ok { - for _, v := range res["added"].([]interface{}) { - fmt.Println("Added:", fmt.Sprint(v)) - } - } - if _, ok := res["not_added"]; ok { - for _, v := range res["not_added"].([]interface{}) { - fmt.Println("Not added:", fmt.Sprint(v)) - } - } - if _, ok := res["removed"]; ok { - for _, v := range res["removed"].([]interface{}) { - fmt.Println("Removed:", fmt.Sprint(v)) - } - } - if _, ok := res["not_removed"]; ok { - for _, v := range res["not_removed"].([]interface{}) { - fmt.Println("Not removed:", fmt.Sprint(v)) - } - } - case "getallowedencryptionpublickeys": - if _, ok := res["allowed_box_pubs"]; !ok { - fmt.Println("All connections are allowed") - } else if res["allowed_box_pubs"] == nil { - fmt.Println("All connections are allowed") - } else { - fmt.Println("Connections are allowed only from the following public box keys:") - for _, v := range res["allowed_box_pubs"].([]interface{}) { - fmt.Println("-", v) - } - } - case "getmulticastinterfaces": - if _, ok := res["multicast_interfaces"]; !ok { - fmt.Println("No multicast interfaces found") - } else if res["multicast_interfaces"] == nil { - fmt.Println("No multicast interfaces found") - } else { - fmt.Println("Multicast peer discovery is active on:") - for _, v := range res["multicast_interfaces"].([]interface{}) { - fmt.Println("-", v) - } - } - case "getsourcesubnets": - if _, ok := res["source_subnets"]; !ok { - fmt.Println("No source subnets found") - } else if res["source_subnets"] == nil { - fmt.Println("No source subnets found") - } else { - fmt.Println("Source subnets:") - for _, v := range res["source_subnets"].([]interface{}) { - fmt.Println("-", v) - } - } - case "getroutes": - if routes, ok := res["routes"].(map[string]interface{}); !ok { - fmt.Println("No routes found") - } else { - if res["routes"] == nil || len(routes) == 0 { - fmt.Println("No routes found") - } else { - fmt.Println("Routes:") - for k, v := range routes { - if pv, ok := v.(string); ok { - fmt.Println("-", k, " via ", pv) - } - } - } - } - case "settunnelrouting": - fallthrough - case "gettunnelrouting": - if enabled, ok := res["enabled"].(bool); !ok { - fmt.Println("Tunnel routing is disabled") - } else if !enabled { - fmt.Println("Tunnel routing is disabled") - } else { - fmt.Println("Tunnel routing is enabled") - } - default: - if json, err := json.MarshalIndent(recv["response"], "", " "); err == nil { - fmt.Println(string(json)) - } - } + handleAll(recv, cmdLineEnv.verbose) } else { logger.Println("Error receiving response:", err) } @@ -448,5 +137,321 @@ func run() int { if v, ok := recv["status"]; ok && v != "success" { return 1 } + return 0 } + +func connect(endpoint string, logger *log.Logger) net.Conn { + var conn net.Conn + + u, err := url.Parse(endpoint) + + if err == nil { + switch strings.ToLower(u.Scheme) { + case "unix": + logger.Println("Connecting to UNIX socket", endpoint[7:]) + conn, err = net.Dial("unix", endpoint[7:]) + case "tcp": + logger.Println("Connecting to TCP socket", u.Host) + conn, err = net.Dial("tcp", u.Host) + default: + logger.Println("Unknown protocol or malformed address - check your endpoint") + err = errors.New("protocol not supported") + } + } else { + logger.Println("Connecting to TCP socket", u.Host) + conn, err = net.Dial("tcp", endpoint) + } + + if err != nil { + panic(err) + } + + return conn +} + +func handleAll(recv map[string]interface{}, verbose bool) { + req := recv["request"].(map[string]interface{}) + res := recv["response"].(map[string]interface{}) + + switch strings.ToLower(req["request"].(string)) { + case "dot": + handleDot(res) + case "list", "getpeers", "getswitchpeers", "getdht", "getsessions", "dhtping": + handleVariousInfo(res, verbose) + case "gettuntap", "settuntap": + handleGetAndSetTunTap(res) + case "getself": + handleGetSelf(res, verbose) + case "getswitchqueues": + handleGetSwitchQueues(res) + case "addpeer", "removepeer", "addallowedencryptionpublickey", "removeallowedencryptionpublickey", "addsourcesubnet", "addroute", "removesourcesubnet", "removeroute": + handleAddsAndRemoves(res) + case "getallowedencryptionpublickeys": + handleGetAllowedEncryptionPublicKeys(res) + case "getmulticastinterfaces": + handleGetMulticastInterfaces(res) + case "getsourcesubnets": + handleGetSourceSubnets(res) + case "getroutes": + handleGetRoutes(res) + case "settunnelrouting": + fallthrough + case "gettunnelrouting": + handleGetTunnelRouting(res) + default: + if json, err := json.MarshalIndent(recv["response"], "", " "); err == nil { + fmt.Println(string(json)) + } + } +} + +func handleDot(res map[string]interface{}) { + fmt.Println(res["dot"]) +} + +func handleVariousInfo(res map[string]interface{}, verbose bool) { + maxWidths := make(map[string]int) + var keyOrder []string + keysOrdered := false + + for _, tlv := range res { + for slk, slv := range tlv.(map[string]interface{}) { + if !keysOrdered { + for k := range slv.(map[string]interface{}) { + if !verbose { + if k == "box_pub_key" || k == "box_sig_key" || k == "nodeinfo" || k == "was_mtu_fixed" { + continue + } + } + keyOrder = append(keyOrder, fmt.Sprint(k)) + } + sort.Strings(keyOrder) + keysOrdered = true + } + for k, v := range slv.(map[string]interface{}) { + if len(fmt.Sprint(slk)) > maxWidths["key"] { + maxWidths["key"] = len(fmt.Sprint(slk)) + } + if len(fmt.Sprint(v)) > maxWidths[k] { + maxWidths[k] = len(fmt.Sprint(v)) + if maxWidths[k] < len(k) { + maxWidths[k] = len(k) + } + } + } + } + + if len(keyOrder) > 0 { + fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s ", "") + for _, v := range keyOrder { + fmt.Printf("%-"+fmt.Sprint(maxWidths[v])+"s ", v) + } + fmt.Println() + } + + for slk, slv := range tlv.(map[string]interface{}) { + fmt.Printf("%-"+fmt.Sprint(maxWidths["key"])+"s ", slk) + for _, k := range keyOrder { + preformatted := slv.(map[string]interface{})[k] + var formatted string + switch k { + case "bytes_sent", "bytes_recvd": + formatted = fmt.Sprintf("%d", uint(preformatted.(float64))) + case "uptime", "last_seen": + seconds := uint(preformatted.(float64)) % 60 + minutes := uint(preformatted.(float64)/60) % 60 + hours := uint(preformatted.(float64) / 60 / 60) + formatted = fmt.Sprintf("%02d:%02d:%02d", hours, minutes, seconds) + default: + formatted = fmt.Sprint(preformatted) + } + fmt.Printf("%-"+fmt.Sprint(maxWidths[k])+"s ", formatted) + } + fmt.Println() + } + } +} + +func handleGetAndSetTunTap(res map[string]interface{}) { + for k, v := range res { + fmt.Println("Interface name:", k) + if mtu, ok := v.(map[string]interface{})["mtu"].(float64); ok { + fmt.Println("Interface MTU:", mtu) + } + if tap_mode, ok := v.(map[string]interface{})["tap_mode"].(bool); ok { + fmt.Println("TAP mode:", tap_mode) + } + } +} + +func handleGetSelf(res map[string]interface{}, verbose bool) { + for k, v := range res["self"].(map[string]interface{}) { + if buildname, ok := v.(map[string]interface{})["build_name"].(string); ok && buildname != "unknown" { + fmt.Println("Build name:", buildname) + } + if buildversion, ok := v.(map[string]interface{})["build_version"].(string); ok && buildversion != "unknown" { + fmt.Println("Build version:", buildversion) + } + fmt.Println("IPv6 address:", k) + if subnet, ok := v.(map[string]interface{})["subnet"].(string); ok { + fmt.Println("IPv6 subnet:", subnet) + } + if boxSigKey, ok := v.(map[string]interface{})["key"].(string); ok { + fmt.Println("Public key:", boxSigKey) + } + if coords, ok := v.(map[string]interface{})["coords"].(string); ok { + fmt.Println("Coords:", coords) + } + if verbose { + if nodeID, ok := v.(map[string]interface{})["node_id"].(string); ok { + fmt.Println("Node ID:", nodeID) + } + if boxPubKey, ok := v.(map[string]interface{})["box_pub_key"].(string); ok { + fmt.Println("Public encryption key:", boxPubKey) + } + if boxSigKey, ok := v.(map[string]interface{})["box_sig_key"].(string); ok { + fmt.Println("Public signing key:", boxSigKey) + } + } + } +} + +func handleGetSwitchQueues(res map[string]interface{}) { + maximumqueuesize := float64(4194304) + portqueues := make(map[float64]float64) + portqueuesize := make(map[float64]float64) + portqueuepackets := make(map[float64]float64) + v := res["switchqueues"].(map[string]interface{}) + if queuecount, ok := v["queues_count"].(float64); ok { + fmt.Printf("Active queue count: %d queues\n", uint(queuecount)) + } + if queuesize, ok := v["queues_size"].(float64); ok { + fmt.Printf("Active queue size: %d bytes\n", uint(queuesize)) + } + if highestqueuecount, ok := v["highest_queues_count"].(float64); ok { + fmt.Printf("Highest queue count: %d queues\n", uint(highestqueuecount)) + } + if highestqueuesize, ok := v["highest_queues_size"].(float64); ok { + fmt.Printf("Highest queue size: %d bytes\n", uint(highestqueuesize)) + } + if m, ok := v["maximum_queues_size"].(float64); ok { + maximumqueuesize = m + fmt.Printf("Maximum queue size: %d bytes\n", uint(maximumqueuesize)) + } + if queues, ok := v["queues"].([]interface{}); ok { + if len(queues) != 0 { + fmt.Println("Active queues:") + for _, v := range queues { + queueport := v.(map[string]interface{})["queue_port"].(float64) + queuesize := v.(map[string]interface{})["queue_size"].(float64) + queuepackets := v.(map[string]interface{})["queue_packets"].(float64) + queueid := v.(map[string]interface{})["queue_id"].(string) + portqueues[queueport]++ + portqueuesize[queueport] += queuesize + portqueuepackets[queueport] += queuepackets + queuesizepercent := (100 / maximumqueuesize) * queuesize + fmt.Printf("- Switch port %d, Stream ID: %v, size: %d bytes (%d%% full), %d packets\n", + uint(queueport), []byte(queueid), uint(queuesize), + uint(queuesizepercent), uint(queuepackets)) + } + } + } + if len(portqueuesize) > 0 && len(portqueuepackets) > 0 { + fmt.Println("Aggregated statistics by switchport:") + for k, v := range portqueuesize { + queuesizepercent := (100 / (portqueues[k] * maximumqueuesize)) * v + fmt.Printf("- Switch port %d, size: %d bytes (%d%% full), %d packets\n", + uint(k), uint(v), uint(queuesizepercent), uint(portqueuepackets[k])) + } + } +} + +func handleAddsAndRemoves(res map[string]interface{}) { + if _, ok := res["added"]; ok { + for _, v := range res["added"].([]interface{}) { + fmt.Println("Added:", fmt.Sprint(v)) + } + } + if _, ok := res["not_added"]; ok { + for _, v := range res["not_added"].([]interface{}) { + fmt.Println("Not added:", fmt.Sprint(v)) + } + } + if _, ok := res["removed"]; ok { + for _, v := range res["removed"].([]interface{}) { + fmt.Println("Removed:", fmt.Sprint(v)) + } + } + if _, ok := res["not_removed"]; ok { + for _, v := range res["not_removed"].([]interface{}) { + fmt.Println("Not removed:", fmt.Sprint(v)) + } + } +} + +func handleGetAllowedEncryptionPublicKeys(res map[string]interface{}) { + if _, ok := res["allowed_box_pubs"]; !ok { + fmt.Println("All connections are allowed") + } else if res["allowed_box_pubs"] == nil { + fmt.Println("All connections are allowed") + } else { + fmt.Println("Connections are allowed only from the following public box keys:") + for _, v := range res["allowed_box_pubs"].([]interface{}) { + fmt.Println("-", v) + } + } +} + +func handleGetMulticastInterfaces(res map[string]interface{}) { + if _, ok := res["multicast_interfaces"]; !ok { + fmt.Println("No multicast interfaces found") + } else if res["multicast_interfaces"] == nil { + fmt.Println("No multicast interfaces found") + } else { + fmt.Println("Multicast peer discovery is active on:") + for _, v := range res["multicast_interfaces"].([]interface{}) { + fmt.Println("-", v) + } + } +} + +func handleGetSourceSubnets(res map[string]interface{}) { + if _, ok := res["source_subnets"]; !ok { + fmt.Println("No source subnets found") + } else if res["source_subnets"] == nil { + fmt.Println("No source subnets found") + } else { + fmt.Println("Source subnets:") + for _, v := range res["source_subnets"].([]interface{}) { + fmt.Println("-", v) + } + } +} + +func handleGetRoutes(res map[string]interface{}) { + if routes, ok := res["routes"].(map[string]interface{}); !ok { + fmt.Println("No routes found") + } else { + if res["routes"] == nil || len(routes) == 0 { + fmt.Println("No routes found") + } else { + fmt.Println("Routes:") + for k, v := range routes { + if pv, ok := v.(string); ok { + fmt.Println("-", k, " via ", pv) + } + } + } + } +} + +func handleGetTunnelRouting(res map[string]interface{}) { + if enabled, ok := res["enabled"].(bool); !ok { + fmt.Println("Tunnel routing is disabled") + } else if !enabled { + fmt.Println("Tunnel routing is disabled") + } else { + fmt.Println("Tunnel routing is enabled") + } +} From ebe366ef3bcb1b22a31225b06d140d013e463647 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Sat, 7 Aug 2021 10:17:21 +0100 Subject: [PATCH 013/334] Add IPReadWriteCloser interface --- src/tuntap/tun.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 4caefe4a..8676ff99 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -11,6 +11,7 @@ package tuntap import ( "errors" "fmt" + "io" "net" //"sync" @@ -22,17 +23,23 @@ import ( "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/ipv6rwc" ) -type MTU uint16 +type IPReadWriteCloser interface { + io.ReadWriteCloser + MaxMTU() uint64 + SetMTU(mtu uint64) + MTU() uint64 + Address() address.Address + Subnet() address.Subnet +} // TunAdapter represents a running TUN interface and extends the // yggdrasil.Adapter type. In order to use the TUN adapter with Yggdrasil, you // should pass this object to the yggdrasil.SetRouterAdapter() function before // calling yggdrasil.Start(). type TunAdapter struct { - rwc *ipv6rwc.ReadWriteCloser + rwc IPReadWriteCloser config *config.NodeConfig log *log.Logger addr address.Address @@ -93,7 +100,7 @@ func MaximumMTU() uint64 { // Init initialises the TUN module. You must have acquired a Listener from // the Yggdrasil core before this point and it must not be in use elsewhere. -func (tun *TunAdapter) Init(rwc *ipv6rwc.ReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { +func (tun *TunAdapter) Init(rwc IPReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { tun.rwc = rwc tun.config = config tun.log = log From 3613614b418ddb7d99b931ce0c6a40e89ed04fc8 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Sat, 7 Aug 2021 12:56:36 -0500 Subject: [PATCH 014/334] Revert "Add IPReadWriteCloser interface" This reverts commit ebe366ef3bcb1b22a31225b06d140d013e463647. --- src/tuntap/tun.go | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 8676ff99..4caefe4a 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -11,7 +11,6 @@ package tuntap import ( "errors" "fmt" - "io" "net" //"sync" @@ -23,23 +22,17 @@ import ( "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/ipv6rwc" ) -type IPReadWriteCloser interface { - io.ReadWriteCloser - MaxMTU() uint64 - SetMTU(mtu uint64) - MTU() uint64 - Address() address.Address - Subnet() address.Subnet -} +type MTU uint16 // TunAdapter represents a running TUN interface and extends the // yggdrasil.Adapter type. In order to use the TUN adapter with Yggdrasil, you // should pass this object to the yggdrasil.SetRouterAdapter() function before // calling yggdrasil.Start(). type TunAdapter struct { - rwc IPReadWriteCloser + rwc *ipv6rwc.ReadWriteCloser config *config.NodeConfig log *log.Logger addr address.Address @@ -100,7 +93,7 @@ func MaximumMTU() uint64 { // Init initialises the TUN module. You must have acquired a Listener from // the Yggdrasil core before this point and it must not be in use elsewhere. -func (tun *TunAdapter) Init(rwc IPReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { +func (tun *TunAdapter) Init(rwc *ipv6rwc.ReadWriteCloser, config *config.NodeConfig, log *log.Logger, options interface{}) error { tun.rwc = rwc tun.config = config tun.log = log From 538ee13669bed5c3637888d0b3ae9e49d833d20c Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 1 Sep 2021 06:16:57 +0500 Subject: [PATCH 015/334] Add type core.AddHandlerFunc --- src/admin/admin.go | 6 +++--- src/core/api.go | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/admin/admin.go b/src/admin/admin.go index d41a48e1..ce831395 100644 --- a/src/admin/admin.go +++ b/src/admin/admin.go @@ -38,8 +38,8 @@ type AdminSocketResponse struct { } type handler struct { - args []string // List of human-readable argument names - handler func(json.RawMessage) (interface{}, error) // First is input map, second is output + args []string // List of human-readable argument names + handler core.AddHandlerFunc // First is input map, second is output } type ListResponse struct { @@ -51,7 +51,7 @@ type ListEntry struct { } // AddHandler is called for each admin function to add the handler and help documentation to the API. -func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(json.RawMessage) (interface{}, error)) error { +func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc core.AddHandlerFunc) error { if _, ok := a.handlers[strings.ToLower(name)]; ok { return errors.New("handler already exists") } diff --git a/src/core/api.go b/src/core/api.go index c312923d..ae13d499 100644 --- a/src/core/api.go +++ b/src/core/api.go @@ -242,9 +242,11 @@ func (c *Core) PublicKey() ed25519.PublicKey { // Hack to get the admin stuff working, TODO something cleaner type AddHandler interface { - AddHandler(name string, args []string, handlerfunc func(json.RawMessage) (interface{}, error)) error + AddHandler(name string, args []string, handlerfunc AddHandlerFunc) error } +type AddHandlerFunc func(json.RawMessage) (interface{}, error) + // SetAdmin must be called after Init and before Start. // It sets the admin handler for NodeInfo and the Debug admin functions. func (c *Core) SetAdmin(a AddHandler) error { From a5f2ba80a2d4aecd61f06e85bc1e69995d821f75 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 1 Sep 2021 06:24:25 +0500 Subject: [PATCH 016/334] Organize code in "src/core/proto.go" --- src/core/proto.go | 83 ++++++++++++++++++++++++++++------------------- 1 file changed, 49 insertions(+), 34 deletions(-) diff --git a/src/core/proto.go b/src/core/proto.go index e60caeff..da9d9b99 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -34,21 +34,26 @@ type keyArray [ed25519.PublicKeySize]byte type protoHandler struct { phony.Inbox - core *Core + nodeinfo nodeinfo - sreqs map[keyArray]*reqInfo - preqs map[keyArray]*reqInfo - dreqs map[keyArray]*reqInfo + core *Core + + getSelfRequests map[keyArray]*reqInfo + getPeersRequests map[keyArray]*reqInfo + getDHTRequests map[keyArray]*reqInfo } func (p *protoHandler) init(core *Core) { p.core = core p.nodeinfo.init(p) - p.sreqs = make(map[keyArray]*reqInfo) - p.preqs = make(map[keyArray]*reqInfo) - p.dreqs = make(map[keyArray]*reqInfo) + + p.getSelfRequests = make(map[keyArray]*reqInfo) + p.getPeersRequests = make(map[keyArray]*reqInfo) + p.getDHTRequests = make(map[keyArray]*reqInfo) } +// Common functions + func (p *protoHandler) handleProto(from phony.Actor, key keyArray, bs []byte) { if len(bs) == 0 { return @@ -85,22 +90,29 @@ func (p *protoHandler) _handleDebug(key keyArray, bs []byte) { } } +func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) { + bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...) + _, _ = p.core.PacketConn.WriteTo(bs, iwt.Addr(key[:])) +} + +// Get self + func (p *protoHandler) sendGetSelfRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.sreqs[key]; info != nil { + if info := p.getSelfRequests[key]; info != nil { info.timer.Stop() - delete(p.sreqs, key) + delete(p.getSelfRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.sreqs[key] == info { - delete(p.sreqs, key) + if p.getSelfRequests[key] == info { + delete(p.getSelfRequests, key) } }) }) - p.sreqs[key] = info + p.getSelfRequests[key] = info p._sendDebug(key, typeDebugGetSelfRequest, nil) }) } @@ -119,29 +131,31 @@ func (p *protoHandler) _handleGetSelfRequest(key keyArray) { } func (p *protoHandler) _handleGetSelfResponse(key keyArray, bs []byte) { - if info := p.sreqs[key]; info != nil { + if info := p.getSelfRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.sreqs, key) + delete(p.getSelfRequests, key) } } +// Get peers + func (p *protoHandler) sendGetPeersRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.preqs[key]; info != nil { + if info := p.getPeersRequests[key]; info != nil { info.timer.Stop() - delete(p.preqs, key) + delete(p.getPeersRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.preqs[key] == info { - delete(p.preqs, key) + if p.getPeersRequests[key] == info { + delete(p.getPeersRequests, key) } }) }) - p.preqs[key] = info + p.getPeersRequests[key] = info p._sendDebug(key, typeDebugGetPeersRequest, nil) }) } @@ -161,29 +175,31 @@ func (p *protoHandler) _handleGetPeersRequest(key keyArray) { } func (p *protoHandler) _handleGetPeersResponse(key keyArray, bs []byte) { - if info := p.preqs[key]; info != nil { + if info := p.getPeersRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.preqs, key) + delete(p.getPeersRequests, key) } } +// Get DHT + func (p *protoHandler) sendGetDHTRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.dreqs[key]; info != nil { + if info := p.getDHTRequests[key]; info != nil { info.timer.Stop() - delete(p.dreqs, key) + delete(p.getDHTRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.dreqs[key] == info { - delete(p.dreqs, key) + if p.getDHTRequests[key] == info { + delete(p.getDHTRequests, key) } }) }) - p.dreqs[key] = info + p.getDHTRequests[key] = info p._sendDebug(key, typeDebugGetDHTRequest, nil) }) } @@ -203,19 +219,14 @@ func (p *protoHandler) _handleGetDHTRequest(key keyArray) { } func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) { - if info := p.dreqs[key]; info != nil { + if info := p.getDHTRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.dreqs, key) + delete(p.getDHTRequests, key) } } -func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) { - bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...) - _, _ = p.core.PacketConn.WriteTo(bs, iwt.Addr(key[:])) -} - -// Admin socket stuff +// Admin socket stuff for "Get self" type DebugGetSelfRequest struct { Key string `json:"key"` @@ -255,6 +266,8 @@ func (p *protoHandler) getSelfHandler(in json.RawMessage) (interface{}, error) { } } +// Admin socket stuff for "Get peers" + type DebugGetPeersRequest struct { Key string `json:"key"` } @@ -303,6 +316,8 @@ func (p *protoHandler) getPeersHandler(in json.RawMessage) (interface{}, error) } } +// Admin socket stuff for "Get DHT" + type DebugGetDHTRequest struct { Key string `json:"key"` } From 3c89781057bed6e87daf3f40523c21d0a569d59b Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Wed, 1 Sep 2021 07:57:45 +0500 Subject: [PATCH 017/334] Align and reorder code for lesser diff --- src/core/proto.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/proto.go b/src/core/proto.go index da9d9b99..1151d006 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -35,8 +35,8 @@ type keyArray [ed25519.PublicKeySize]byte type protoHandler struct { phony.Inbox + core *Core nodeinfo nodeinfo - core *Core getSelfRequests map[keyArray]*reqInfo getPeersRequests map[keyArray]*reqInfo From 571186ca772e96b1f4226b2dd56252b9aa3e5a30 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Fri, 3 Sep 2021 01:45:30 +0500 Subject: [PATCH 018/334] Rename protohandler attributes --- src/core/proto.go | 54 +++++++++++++++++++++++------------------------ 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/core/proto.go b/src/core/proto.go index 1151d006..3045972e 100644 --- a/src/core/proto.go +++ b/src/core/proto.go @@ -38,18 +38,18 @@ type protoHandler struct { core *Core nodeinfo nodeinfo - getSelfRequests map[keyArray]*reqInfo - getPeersRequests map[keyArray]*reqInfo - getDHTRequests map[keyArray]*reqInfo + selfRequests map[keyArray]*reqInfo + peersRequests map[keyArray]*reqInfo + dhtRequests map[keyArray]*reqInfo } func (p *protoHandler) init(core *Core) { p.core = core p.nodeinfo.init(p) - p.getSelfRequests = make(map[keyArray]*reqInfo) - p.getPeersRequests = make(map[keyArray]*reqInfo) - p.getDHTRequests = make(map[keyArray]*reqInfo) + p.selfRequests = make(map[keyArray]*reqInfo) + p.peersRequests = make(map[keyArray]*reqInfo) + p.dhtRequests = make(map[keyArray]*reqInfo) } // Common functions @@ -99,20 +99,20 @@ func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) { func (p *protoHandler) sendGetSelfRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.getSelfRequests[key]; info != nil { + if info := p.selfRequests[key]; info != nil { info.timer.Stop() - delete(p.getSelfRequests, key) + delete(p.selfRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.getSelfRequests[key] == info { - delete(p.getSelfRequests, key) + if p.selfRequests[key] == info { + delete(p.selfRequests, key) } }) }) - p.getSelfRequests[key] = info + p.selfRequests[key] = info p._sendDebug(key, typeDebugGetSelfRequest, nil) }) } @@ -131,10 +131,10 @@ func (p *protoHandler) _handleGetSelfRequest(key keyArray) { } func (p *protoHandler) _handleGetSelfResponse(key keyArray, bs []byte) { - if info := p.getSelfRequests[key]; info != nil { + if info := p.selfRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.getSelfRequests, key) + delete(p.selfRequests, key) } } @@ -142,20 +142,20 @@ func (p *protoHandler) _handleGetSelfResponse(key keyArray, bs []byte) { func (p *protoHandler) sendGetPeersRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.getPeersRequests[key]; info != nil { + if info := p.peersRequests[key]; info != nil { info.timer.Stop() - delete(p.getPeersRequests, key) + delete(p.peersRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.getPeersRequests[key] == info { - delete(p.getPeersRequests, key) + if p.peersRequests[key] == info { + delete(p.peersRequests, key) } }) }) - p.getPeersRequests[key] = info + p.peersRequests[key] = info p._sendDebug(key, typeDebugGetPeersRequest, nil) }) } @@ -175,10 +175,10 @@ func (p *protoHandler) _handleGetPeersRequest(key keyArray) { } func (p *protoHandler) _handleGetPeersResponse(key keyArray, bs []byte) { - if info := p.getPeersRequests[key]; info != nil { + if info := p.peersRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.getPeersRequests, key) + delete(p.peersRequests, key) } } @@ -186,20 +186,20 @@ func (p *protoHandler) _handleGetPeersResponse(key keyArray, bs []byte) { func (p *protoHandler) sendGetDHTRequest(key keyArray, callback func([]byte)) { p.Act(nil, func() { - if info := p.getDHTRequests[key]; info != nil { + if info := p.dhtRequests[key]; info != nil { info.timer.Stop() - delete(p.getDHTRequests, key) + delete(p.dhtRequests, key) } info := new(reqInfo) info.callback = callback info.timer = time.AfterFunc(time.Minute, func() { p.Act(nil, func() { - if p.getDHTRequests[key] == info { - delete(p.getDHTRequests, key) + if p.dhtRequests[key] == info { + delete(p.dhtRequests, key) } }) }) - p.getDHTRequests[key] = info + p.dhtRequests[key] = info p._sendDebug(key, typeDebugGetDHTRequest, nil) }) } @@ -219,10 +219,10 @@ func (p *protoHandler) _handleGetDHTRequest(key keyArray) { } func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) { - if info := p.getDHTRequests[key]; info != nil { + if info := p.dhtRequests[key]; info != nil { info.timer.Stop() info.callback(bs) - delete(p.getDHTRequests, key) + delete(p.dhtRequests, key) } } From 52345a2de49d47bfad23b5cf45435cd84fd971bc Mon Sep 17 00:00:00 2001 From: Fyodor Ustinov Date: Tue, 21 Sep 2021 23:19:25 +0300 Subject: [PATCH 019/334] Check tun.config is not equal to nil before usage (#830) We have to check tun.config is not nil before first use, not after. --- src/tuntap/tun.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index 4caefe4a..eddccbcd 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -114,11 +114,11 @@ func (tun *TunAdapter) _start() error { if tun.isOpen { return errors.New("TUN module is already started") } - tun.config.RLock() - defer tun.config.RUnlock() if tun.config == nil { return errors.New("no configuration available to TUN") } + tun.config.RLock() + defer tun.config.RUnlock() tun.addr = tun.rwc.Address() tun.subnet = tun.rwc.Subnet() addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1) From 1c7deb72db461ee4c1ec96137b9242fb6acd1837 Mon Sep 17 00:00:00 2001 From: Paul Dee <647633+systemcrash@users.noreply.github.com> Date: Tue, 21 Sep 2021 22:19:40 +0200 Subject: [PATCH 020/334] Align struct elements to byte boundaries: reduce memory footprint. (#834) --- cmd/yggdrasil/main.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index 95d40151..58b8230d 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -185,14 +185,14 @@ func setLogLevel(loglevel string, logger *log.Logger) { type yggArgs struct { genconf bool useconf bool - useconffile string normaliseconf bool confjson bool autoconf bool ver bool - logto string getaddr bool getsnet bool + useconffile string + logto string loglevel string } From 529a33034becaf0f44fc5b3069fb33f46e4c2bcd Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 23 Sep 2021 04:34:58 -0500 Subject: [PATCH 021/334] gofmt to add new build comments --- src/core/debug.go | 1 + src/core/tcp_darwin.go | 1 + src/core/tcp_linux.go | 1 + src/core/tcp_other.go | 1 + src/defaults/defaults_darwin.go | 1 + src/defaults/defaults_freebsd.go | 1 + src/defaults/defaults_linux.go | 1 + src/defaults/defaults_openbsd.go | 1 + src/defaults/defaults_other.go | 1 + src/defaults/defaults_windows.go | 1 + src/multicast/multicast_darwin.go | 1 + src/multicast/multicast_other.go | 1 + src/multicast/multicast_unix.go | 1 + src/multicast/multicast_windows.go | 1 + src/tuntap/tun_bsd.go | 1 + src/tuntap/tun_darwin.go | 1 + src/tuntap/tun_linux.go | 1 + src/tuntap/tun_other.go | 1 + src/tuntap/tun_windows.go | 1 + 19 files changed, 19 insertions(+) diff --git a/src/core/debug.go b/src/core/debug.go index 0fc08259..eb406798 100644 --- a/src/core/debug.go +++ b/src/core/debug.go @@ -1,3 +1,4 @@ +//go:build debug // +build debug package core diff --git a/src/core/tcp_darwin.go b/src/core/tcp_darwin.go index 6b85c621..2ea3abc8 100644 --- a/src/core/tcp_darwin.go +++ b/src/core/tcp_darwin.go @@ -1,3 +1,4 @@ +//go:build darwin // +build darwin package core diff --git a/src/core/tcp_linux.go b/src/core/tcp_linux.go index 558b4e56..e59c3121 100644 --- a/src/core/tcp_linux.go +++ b/src/core/tcp_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package core diff --git a/src/core/tcp_other.go b/src/core/tcp_other.go index 97b81ed1..8dd76f28 100644 --- a/src/core/tcp_other.go +++ b/src/core/tcp_other.go @@ -1,3 +1,4 @@ +//go:build !darwin && !linux // +build !darwin,!linux package core diff --git a/src/defaults/defaults_darwin.go b/src/defaults/defaults_darwin.go index e16f398f..060ce814 100644 --- a/src/defaults/defaults_darwin.go +++ b/src/defaults/defaults_darwin.go @@ -1,3 +1,4 @@ +//go:build darwin // +build darwin package defaults diff --git a/src/defaults/defaults_freebsd.go b/src/defaults/defaults_freebsd.go index 6c3e1c60..84df48ad 100644 --- a/src/defaults/defaults_freebsd.go +++ b/src/defaults/defaults_freebsd.go @@ -1,3 +1,4 @@ +//go:build freebsd // +build freebsd package defaults diff --git a/src/defaults/defaults_linux.go b/src/defaults/defaults_linux.go index 95c7ae95..c7f5f119 100644 --- a/src/defaults/defaults_linux.go +++ b/src/defaults/defaults_linux.go @@ -1,3 +1,4 @@ +//go:build linux // +build linux package defaults diff --git a/src/defaults/defaults_openbsd.go b/src/defaults/defaults_openbsd.go index ef339546..0ec877ca 100644 --- a/src/defaults/defaults_openbsd.go +++ b/src/defaults/defaults_openbsd.go @@ -1,3 +1,4 @@ +//go:build openbsd // +build openbsd package defaults diff --git a/src/defaults/defaults_other.go b/src/defaults/defaults_other.go index d1417322..37637425 100644 --- a/src/defaults/defaults_other.go +++ b/src/defaults/defaults_other.go @@ -1,3 +1,4 @@ +//go:build !linux && !darwin && !windows && !openbsd && !freebsd // +build !linux,!darwin,!windows,!openbsd,!freebsd package defaults diff --git a/src/defaults/defaults_windows.go b/src/defaults/defaults_windows.go index e81d09cf..c1ea9689 100644 --- a/src/defaults/defaults_windows.go +++ b/src/defaults/defaults_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package defaults diff --git a/src/multicast/multicast_darwin.go b/src/multicast/multicast_darwin.go index e7075c0a..7ad0c543 100644 --- a/src/multicast/multicast_darwin.go +++ b/src/multicast/multicast_darwin.go @@ -1,3 +1,4 @@ +//go:build darwin // +build darwin package multicast diff --git a/src/multicast/multicast_other.go b/src/multicast/multicast_other.go index dfcf625f..9977951c 100644 --- a/src/multicast/multicast_other.go +++ b/src/multicast/multicast_other.go @@ -1,3 +1,4 @@ +//go:build !linux && !darwin && !netbsd && !freebsd && !openbsd && !dragonflybsd && !windows // +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows package multicast diff --git a/src/multicast/multicast_unix.go b/src/multicast/multicast_unix.go index 1ff48b17..9c822fcf 100644 --- a/src/multicast/multicast_unix.go +++ b/src/multicast/multicast_unix.go @@ -1,3 +1,4 @@ +//go:build linux || netbsd || freebsd || openbsd || dragonflybsd // +build linux netbsd freebsd openbsd dragonflybsd package multicast diff --git a/src/multicast/multicast_windows.go b/src/multicast/multicast_windows.go index 3666faaa..515412a4 100644 --- a/src/multicast/multicast_windows.go +++ b/src/multicast/multicast_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package multicast diff --git a/src/tuntap/tun_bsd.go b/src/tuntap/tun_bsd.go index 75158857..fe36266b 100644 --- a/src/tuntap/tun_bsd.go +++ b/src/tuntap/tun_bsd.go @@ -1,3 +1,4 @@ +//go:build openbsd || freebsd // +build openbsd freebsd package tuntap diff --git a/src/tuntap/tun_darwin.go b/src/tuntap/tun_darwin.go index 75938881..6f6e2528 100644 --- a/src/tuntap/tun_darwin.go +++ b/src/tuntap/tun_darwin.go @@ -1,3 +1,4 @@ +//go:build !mobile // +build !mobile package tuntap diff --git a/src/tuntap/tun_linux.go b/src/tuntap/tun_linux.go index 0a845368..f849c00f 100644 --- a/src/tuntap/tun_linux.go +++ b/src/tuntap/tun_linux.go @@ -1,3 +1,4 @@ +//go:build !mobile // +build !mobile package tuntap diff --git a/src/tuntap/tun_other.go b/src/tuntap/tun_other.go index c0321267..8ce24953 100644 --- a/src/tuntap/tun_other.go +++ b/src/tuntap/tun_other.go @@ -1,3 +1,4 @@ +//go:build !linux && !darwin && !windows && !openbsd && !freebsd && !mobile // +build !linux,!darwin,!windows,!openbsd,!freebsd,!mobile package tuntap diff --git a/src/tuntap/tun_windows.go b/src/tuntap/tun_windows.go index 7b7ee710..8dce7274 100644 --- a/src/tuntap/tun_windows.go +++ b/src/tuntap/tun_windows.go @@ -1,3 +1,4 @@ +//go:build windows // +build windows package tuntap From 86e5306eec42324a7e68b4a5e37b7b9d89e98c83 Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 23 Sep 2021 04:35:31 -0500 Subject: [PATCH 022/334] fix race from mutex that wasn't held long enough --- src/ipv6rwc/ipv6rwc.go | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/ipv6rwc/ipv6rwc.go b/src/ipv6rwc/ipv6rwc.go index 1c715f0f..f71c638e 100644 --- a/src/ipv6rwc/ipv6rwc.go +++ b/src/ipv6rwc/ipv6rwc.go @@ -129,6 +129,7 @@ func (k *keyStore) sendToSubnet(subnet address.Subnet, bs []byte) { func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.mutex.Lock() + defer k.mutex.Unlock() var kArray keyArray copy(kArray[:], key) var info *keyInfo @@ -140,8 +141,6 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.keyToInfo[info.key] = info k.addrToInfo[info.address] = info k.subnetToInfo[info.subnet] = info - k.resetTimeout(info) - k.mutex.Unlock() if buf := k.addrBuffer[info.address]; buf != nil { k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) delete(k.addrBuffer, info.address) @@ -150,10 +149,8 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) delete(k.subnetBuffer, info.subnet) } - } else { - k.resetTimeout(info) - k.mutex.Unlock() } + k.resetTimeout(info) return info } From e5d638ff4bdd1bf9847e6e645b658b14f60278ae Mon Sep 17 00:00:00 2001 From: Arceliar Date: Thu, 23 Sep 2021 04:39:12 -0500 Subject: [PATCH 023/334] better way to empty ipv6rwc buffer --- src/ipv6rwc/ipv6rwc.go | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/ipv6rwc/ipv6rwc.go b/src/ipv6rwc/ipv6rwc.go index f71c638e..fc2a688f 100644 --- a/src/ipv6rwc/ipv6rwc.go +++ b/src/ipv6rwc/ipv6rwc.go @@ -129,10 +129,10 @@ func (k *keyStore) sendToSubnet(subnet address.Subnet, bs []byte) { func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.mutex.Lock() - defer k.mutex.Unlock() var kArray keyArray copy(kArray[:], key) var info *keyInfo + var packets [][]byte if info = k.keyToInfo[kArray]; info == nil { info = new(keyInfo) info.key = kArray @@ -142,15 +142,19 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo { k.addrToInfo[info.address] = info k.subnetToInfo[info.subnet] = info if buf := k.addrBuffer[info.address]; buf != nil { - k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) + packets = append(packets, buf.packet) delete(k.addrBuffer, info.address) } if buf := k.subnetBuffer[info.subnet]; buf != nil { - k.core.WriteTo(buf.packet, iwt.Addr(info.key[:])) + packets = append(packets, buf.packet) delete(k.subnetBuffer, info.subnet) } } k.resetTimeout(info) + k.mutex.Unlock() + for _, packet := range packets { + k.core.WriteTo(packet, iwt.Addr(info.key[:])) + } return info } From 9a1d1df85edb5442ec75382334fd5a265382800f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Thu, 23 Sep 2021 12:11:03 +0100 Subject: [PATCH 024/334] Use newer Xcode image for macOS builds in CircleCI --- .circleci/config.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.circleci/config.yml b/.circleci/config.yml index 5ebd26e2..fa49c34d 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -105,7 +105,7 @@ jobs: build-macos: macos: - xcode: "10.0.0" + xcode: "13.0.0" working_directory: ~/go/src/github.com/yggdrasil-network/yggdrasil-go From 99227b60cedfb278b1b6d6ac9ae965f47fce5ccf Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 28 Sep 2021 11:02:15 +0100 Subject: [PATCH 025/334] Update CI to use Go 1.17, produce Apple Silicon builds (closes #844) --- .circleci/config.yml | 16 ++++--- contrib/macos/create-pkg.sh | 4 ++ src/multicast/multicast_darwin.go | 40 ++-------------- src/multicast/multicast_darwin_cgo.go | 69 +++++++++++++++++++++++++++ src/multicast/multicast_other.go | 4 +- 5 files changed, 89 insertions(+), 44 deletions(-) create mode 100644 src/multicast/multicast_darwin_cgo.go diff --git a/.circleci/config.yml b/.circleci/config.yml index fa49c34d..065f2b0b 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -5,7 +5,7 @@ version: 2.1 jobs: lint: docker: - - image: circleci/golang:1.16 + - image: circleci/golang:1.17 steps: - checkout @@ -23,7 +23,7 @@ jobs: build-linux: docker: - - image: circleci/golang:1.16 + - image: circleci/golang:1.17 steps: - checkout @@ -124,11 +124,11 @@ jobs: echo -e "Host *\n\tStrictHostKeyChecking no\n" >> ~/.ssh/config - run: - name: Install Go 1.16 + name: Install Go 1.17 command: | cd /tmp - curl -LO https://dl.google.com/go/go1.16.darwin-amd64.pkg - sudo installer -pkg /tmp/go1.16.darwin-amd64.pkg -target / + curl -LO https://dl.google.com/go/go1.17.darwin-amd64.pkg + sudo installer -pkg /tmp/go1.17.darwin-amd64.pkg -target / #- run: # name: Install Gomobile @@ -142,11 +142,15 @@ jobs: GO111MODULE=on GOOS=darwin GOARCH=amd64 ./build cp yggdrasil /tmp/upload/$CINAME-$CIVERSION-darwin-amd64 cp yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-darwin-amd64; + GO111MODULE=on GOOS=darwin GOARCH=arm64 ./build + cp yggdrasil /tmp/upload/$CINAME-$CIVERSION-darwin-arm64 + cp yggdrasilctl /tmp/upload/$CINAME-$CIVERSION-yggdrasilctl-darwin-arm64; - run: name: Build for macOS (.pkg format) command: | PKGARCH=amd64 sh contrib/macos/create-pkg.sh + PKGARCH=arm64 sh contrib/macos/create-pkg.sh mv *.pkg /tmp/upload/ #- run: @@ -164,7 +168,7 @@ jobs: build-other: docker: - - image: circleci/golang:1.16 + - image: circleci/golang:1.17 steps: - checkout diff --git a/contrib/macos/create-pkg.sh b/contrib/macos/create-pkg.sh index cc9a74f7..919c45ed 100755 --- a/contrib/macos/create-pkg.sh +++ b/contrib/macos/create-pkg.sh @@ -15,6 +15,10 @@ command -v mkbom >/dev/null 2>&1 || ( sudo make install || (echo "Failed to build mkbom"; exit 1) ) +# Build Yggdrasil +echo "running GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build" +GO111MODULE=on GOOS=darwin GOARCH=${PKGARCH-amd64} ./build + # Check if we can find the files we need - they should # exist if you are running this script from the root of # the yggdrasil-go repo and you have ran ./build diff --git a/src/multicast/multicast_darwin.go b/src/multicast/multicast_darwin.go index 7ad0c543..22cf3998 100644 --- a/src/multicast/multicast_darwin.go +++ b/src/multicast/multicast_darwin.go @@ -1,49 +1,17 @@ -//go:build darwin -// +build darwin +//go:build !cgo && (darwin || ios) +// +build !cgo +// +build darwin ios package multicast -/* -#cgo CFLAGS: -x objective-c -#cgo LDFLAGS: -framework Foundation -#import -NSNetServiceBrowser *serviceBrowser; -void StartAWDLBrowsing() { - if (serviceBrowser == nil) { - serviceBrowser = [[NSNetServiceBrowser alloc] init]; - serviceBrowser.includesPeerToPeer = YES; - } - [serviceBrowser searchForServicesOfType:@"_yggdrasil._tcp" inDomain:@""]; -} -void StopAWDLBrowsing() { - if (serviceBrowser == nil) { - return; - } - [serviceBrowser stop]; -} -*/ -import "C" import ( "syscall" - "time" "golang.org/x/sys/unix" ) func (m *Multicast) _multicastStarted() { - if !m.isOpen { - return - } - C.StopAWDLBrowsing() - for intf := range m._interfaces { - if intf == "awdl0" { - C.StartAWDLBrowsing() - break - } - } - time.AfterFunc(time.Minute, func() { - m.Act(nil, m._multicastStarted) - }) + } func (m *Multicast) multicastReuse(network string, address string, c syscall.RawConn) error { diff --git a/src/multicast/multicast_darwin_cgo.go b/src/multicast/multicast_darwin_cgo.go new file mode 100644 index 00000000..b7d7358c --- /dev/null +++ b/src/multicast/multicast_darwin_cgo.go @@ -0,0 +1,69 @@ +//go:build (darwin && cgo) || (ios && cgo) +// +build darwin,cgo ios,cgo + +package multicast + +/* +#cgo CFLAGS: -x objective-c +#cgo LDFLAGS: -framework Foundation +#import +NSNetServiceBrowser *serviceBrowser; +void StartAWDLBrowsing() { + if (serviceBrowser == nil) { + serviceBrowser = [[NSNetServiceBrowser alloc] init]; + serviceBrowser.includesPeerToPeer = YES; + } + [serviceBrowser searchForServicesOfType:@"_yggdrasil._tcp" inDomain:@""]; +} +void StopAWDLBrowsing() { + if (serviceBrowser == nil) { + return; + } + [serviceBrowser stop]; +} +*/ +import "C" +import ( + "syscall" + "time" + + "golang.org/x/sys/unix" +) + +func (m *Multicast) _multicastStarted() { + if !m.isOpen { + return + } + C.StopAWDLBrowsing() + for intf := range m._interfaces { + if intf == "awdl0" { + C.StartAWDLBrowsing() + break + } + } + time.AfterFunc(time.Minute, func() { + m.Act(nil, m._multicastStarted) + }) +} + +func (m *Multicast) multicastReuse(network string, address string, c syscall.RawConn) error { + var control error + var reuseport error + var recvanyif error + + control = c.Control(func(fd uintptr) { + reuseport = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1) + + // sys/socket.h: #define SO_RECV_ANYIF 0x1104 + recvanyif = unix.SetsockoptInt(int(fd), syscall.SOL_SOCKET, 0x1104, 1) + }) + + switch { + case reuseport != nil: + return reuseport + case recvanyif != nil: + return recvanyif + default: + return control + } +} diff --git a/src/multicast/multicast_other.go b/src/multicast/multicast_other.go index 9977951c..263f4ffc 100644 --- a/src/multicast/multicast_other.go +++ b/src/multicast/multicast_other.go @@ -1,5 +1,5 @@ -//go:build !linux && !darwin && !netbsd && !freebsd && !openbsd && !dragonflybsd && !windows -// +build !linux,!darwin,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows +//go:build !linux && !darwin && !ios && !netbsd && !freebsd && !openbsd && !dragonflybsd && !windows +// +build !linux,!darwin,!ios,!netbsd,!freebsd,!openbsd,!dragonflybsd,!windows package multicast From 4859accbb038f8db3c3a541d0f3f3f76de75b9fb Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Tue, 2 Nov 2021 18:03:16 +0000 Subject: [PATCH 026/334] Fix panic in `address.GetKey()` (fixes #860) --- src/address/address.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/address/address.go b/src/address/address.go index 0e2400ed..c7f2eb46 100644 --- a/src/address/address.go +++ b/src/address/address.go @@ -129,7 +129,11 @@ func (a *Address) GetKey() ed25519.PublicKey { bits <<= byte(idx % 8) keyIdx := keyOffset + (idx - addrOffset) bits >>= byte(keyIdx % 8) - key[keyIdx/8] |= bits + idx := keyIdx / 8 + if idx >= len(key) { + break + } + key[idx] |= bits } for idx := range key { key[idx] = ^key[idx] From 5c19f3f88c6b664456721a933c4e37c85214504d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Nov 2021 10:33:00 +0000 Subject: [PATCH 027/334] Update dependencies --- go.mod | 11 +++++------ go.sum | 52 ++++++++++++++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 26 deletions(-) diff --git a/go.mod b/go.mod index 398504cb..05044531 100644 --- a/go.mod +++ b/go.mod @@ -17,10 +17,9 @@ require ( github.com/mitchellh/mapstructure v1.4.1 github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect - golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect - golang.org/x/net v0.0.0-20210610132358-84b48f89b13b - golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 - golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f - golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 - golang.zx2c4.com/wireguard/windows v0.3.14 + golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 + golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 + golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b + golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a + golang.zx2c4.com/wireguard/windows v0.4.12 ) diff --git a/go.sum b/go.sum index 5d11fad6..e6df746b 100644 --- a/go.sum +++ b/go.sum @@ -38,42 +38,54 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= +github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= -golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A= -golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU= +golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ= -golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= +golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f h1:yQJrRE0hDxDFmZLlRaw+3vusO4fwNHgHIjUOMO7bHYI= -golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0= +golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg= -golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM= -golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= -golang.zx2c4.com/wireguard/windows v0.3.14 h1:5yIDYyrQyGkLqV+tzY4ilMNeIvQeMXAz0glZz9u179A= -golang.zx2c4.com/wireguard/windows v0.3.14/go.mod h1:3P4IEAsb+BjlKZmpUXgy74c0iX9AVwwr3WcVJ8nPgME= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= +golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw= +golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= +golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA= +golang.zx2c4.com/wireguard/windows v0.4.12/go.mod h1:PW4y+d9oY83XU9rRwRwrJDwEMuhVjMxu2gfD1cfzS7w= From 4f3117d81d76d5219063016e458c4d2f748ff05d Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Nov 2021 17:40:06 +0000 Subject: [PATCH 028/334] Use `network-online.target` instead of `network.target` for systemd service unit --- contrib/systemd/yggdrasil.service | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/contrib/systemd/yggdrasil.service b/contrib/systemd/yggdrasil.service index 27d27907..f8c2dd22 100644 --- a/contrib/systemd/yggdrasil.service +++ b/contrib/systemd/yggdrasil.service @@ -1,8 +1,8 @@ [Unit] Description=yggdrasil -Wants=network.target +Wants=network-online.target Wants=yggdrasil-default-config.service -After=network.target +After=network-online.target After=yggdrasil-default-config.service [Service] From 1f64319712a83aaa7f79789ab247db9542b04dbf Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Nov 2021 17:53:35 +0000 Subject: [PATCH 029/334] Version 0.4.1 --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index bdb634f3..05291f85 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,19 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.4.1] - 2021-11-03 +### Added +- TLS peerings now support Server Name Indication (SNI) + - The SNI is sent automatically if the peering URI contains a DNS name + - A custom SNI can be specified by adding the `?sni=domain.com` parameter to the peering URI +- A new `ipv6rwc` API package now implements the IPv6-specific logic separate from the `tun` package + +### Fixed +- A crash when calculating the partial public key for very high IPv6 addresses has been fixed +- A crash due to a concurrent map write has been fixed +- A crash due to missing TUN configuration has been fixed +- A race condition in the keystore code has been fixed + ## [0.4.0] - 2021-07-04 ### Added - New routing scheme, which is backwards incompatible with previous versions of Yggdrasil From 03a5cce5bb739d5f3ad5d9877c38817cf88eccd5 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Nov 2021 20:03:27 +0000 Subject: [PATCH 030/334] Revert Wireguard update This reverts commit 5c19f3f88c6b664456721a933c4e37c85214504d. --- go.mod | 11 ++++++----- go.sum | 52 ++++++++++++++++++++-------------------------------- 2 files changed, 26 insertions(+), 37 deletions(-) diff --git a/go.mod b/go.mod index 05044531..398504cb 100644 --- a/go.mod +++ b/go.mod @@ -17,9 +17,10 @@ require ( github.com/mitchellh/mapstructure v1.4.1 github.com/vishvananda/netlink v1.1.0 github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f // indirect - golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 - golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 - golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b - golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a - golang.zx2c4.com/wireguard/windows v0.4.12 + golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a // indirect + golang.org/x/net v0.0.0-20210610132358-84b48f89b13b + golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 + golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f + golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 + golang.zx2c4.com/wireguard/windows v0.3.14 ) diff --git a/go.sum b/go.sum index e6df746b..5d11fad6 100644 --- a/go.sum +++ b/go.sum @@ -38,54 +38,42 @@ github.com/vishvananda/netlink v1.1.0/go.mod h1:cTgwzPIzzgDAYoQrMm0EdrjRUBkTqKYp github.com/vishvananda/netns v0.0.0-20191106174202-0a2b9b5464df/go.mod h1:JP3t17pCcGlemwknint6hfoeCVQrEMVwxRLRjXpq+BU= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvVn1ZaTIVp+3vuYAXFe3OJEvjbUYJLaA= github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= -github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519 h1:7I4JAnoQBe7ZtJcBaYHi5UtiO8tQHbUSXxL+pnGRANg= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/crypto v0.0.0-20210506145944-38f3c27a63bf/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a h1:kr2P4QFmQr29mSLA43kwrOcgcReGTfbE9N577tCTuBc= +golang.org/x/crypto v0.0.0-20210513164829-c07d793c2f9a/go.mod h1:P+XmwS30IXTQdn5tA2iutPOUgjI07+tq3H3K9MVA1s8= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20210927181540-4e4d966f7476/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211011170408-caeb26a5c8c0/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20211101193420-4a448f8816b3 h1:VrJZAjbekhoRn7n5FBujY31gboH+iB3pdLxn3gE9FjU= -golang.org/x/net v0.0.0-20211101193420-4a448f8816b3/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/net v0.0.0-20210510120150-4163338589ed/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b h1:k+E048sYJHyVnsr1GDrRZWQ32D2C7lWs9JRc0bel53A= +golang.org/x/net v0.0.0-20210610132358-84b48f89b13b/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190606203320-7fc4e5ec1444/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200217220822-9197077df867/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200602225109-6fdc65e7d980/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201018230417-eeed37f84f13/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210309040221-94ec62e08169/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211007075335-d3039528d8ac/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20211102192858-4dd72447c267 h1:7zYaz3tjChtpayGDzu6H0hDAUM5zIGA2XW7kRNgQ0jc= -golang.org/x/sys v0.0.0-20211102192858-4dd72447c267/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210611083646-a4fc73990273 h1:faDu4veV+8pcThn4fewv6TVlNCezafGoC1gM/mxQLbQ= +golang.org/x/sys v0.0.0-20210611083646-a4fc73990273/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b h1:NXqSWXSRUSCaFuvitrWtU169I3876zRTalMRbfd6LL0= -golang.org/x/text v0.3.8-0.20211004125949-5bd84dd9b33b/go.mod h1:EFNZuWvGYxIRUEX+K8UmCFwYmZjqcrnq15ZuVldZkZ0= +golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f h1:yQJrRE0hDxDFmZLlRaw+3vusO4fwNHgHIjUOMO7bHYI= +golang.org/x/text v0.3.7-0.20210503195748-5c7c50ebbd4f/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.1.7/go.mod h1:LGqMHiF4EqQNHR1JncWGqT5BVaXmza+X+BDGol+dOxo= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.zx2c4.com/wireguard v0.0.0-20211012062646-82d2aa87aa62/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= -golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a h1:tTbyylK9/D3u/wEP26Vx7L700UpY48nhioJWZM1vhZw= -golang.zx2c4.com/wireguard v0.0.0-20211017052713-f87e87af0d9a/go.mod h1:id8Oh3eCCmpj9uVGWVjsUAl6UPX5ysMLzu6QxJU2UOU= -golang.zx2c4.com/wireguard/windows v0.4.12 h1:CUmbdWKVNzTSsVb4yUAiEwL3KsabdJkEPdDjCHxBlhA= -golang.zx2c4.com/wireguard/windows v0.4.12/go.mod h1:PW4y+d9oY83XU9rRwRwrJDwEMuhVjMxu2gfD1cfzS7w= +golang.zx2c4.com/wireguard v0.0.0-20210510202332-9844c74f67ec/go.mod h1:a057zjmoc00UN7gVkaJt2sXVK523kMJcogDTEvPIasg= +golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2 h1:wfOOSvHgIzTZ9h5Vb6yUFZNn7uf3bT7PeYsHOO7tYDM= +golang.zx2c4.com/wireguard v0.0.0-20210604143328-f9b48a961cd2/go.mod h1:laHzsbfMhGSobUmruXWAyMKKHSqvIcrqZJMyHD+/3O8= +golang.zx2c4.com/wireguard/windows v0.3.14 h1:5yIDYyrQyGkLqV+tzY4ilMNeIvQeMXAz0glZz9u179A= +golang.zx2c4.com/wireguard/windows v0.3.14/go.mod h1:3P4IEAsb+BjlKZmpUXgy74c0iX9AVwwr3WcVJ8nPgME= From e4e58831bf6b3d2a194c12c4e8dc3fd7351e6165 Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Wed, 3 Nov 2021 22:16:53 +0000 Subject: [PATCH 031/334] Version 0.4.2 --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 05291f85..bb418b11 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0. - in case of vulnerabilities. --> +## [0.4.2] - 2021-11-03 +### Fixed +- Reverted a dependency update which resulted in problems building with Go 1.16 and running on Windows + ## [0.4.1] - 2021-11-03 ### Added - TLS peerings now support Server Name Indication (SNI) From 87e936195ebaa1d11475d6fb3a73958c654be977 Mon Sep 17 00:00:00 2001 From: Alex Kotov Date: Thu, 4 Nov 2021 13:05:53 +0500 Subject: [PATCH 032/334] Add some tests (#828) * Add tests * Add tests * Add tests * Add tests * Fix code style * Remove unnecessary tests --- src/address/address_test.go | 114 ++++++++++++++++++++++++++++++++++++ src/config/config_test.go | 54 +++++++++++++++++ 2 files changed, 168 insertions(+) create mode 100644 src/address/address_test.go create mode 100644 src/config/config_test.go diff --git a/src/address/address_test.go b/src/address/address_test.go new file mode 100644 index 00000000..a7939e0f --- /dev/null +++ b/src/address/address_test.go @@ -0,0 +1,114 @@ +package address + +import ( + "bytes" + "crypto/ed25519" + "math/rand" + "testing" +) + +func TestAddress_Address_IsValid(t *testing.T) { + var address Address + rand.Read(address[:]) + + address[0] = 0 + + if address.IsValid() { + t.Fatal("invalid address marked as valid") + } + + address[0] = 0x03 + + if address.IsValid() { + t.Fatal("invalid address marked as valid") + } + + address[0] = 0x02 + + if !address.IsValid() { + t.Fatal("valid address marked as invalid") + } +} + +func TestAddress_Subnet_IsValid(t *testing.T) { + var subnet Subnet + rand.Read(subnet[:]) + + subnet[0] = 0 + + if subnet.IsValid() { + t.Fatal("invalid subnet marked as valid") + } + + subnet[0] = 0x02 + + if subnet.IsValid() { + t.Fatal("invalid subnet marked as valid") + } + + subnet[0] = 0x03 + + if !subnet.IsValid() { + t.Fatal("valid subnet marked as invalid") + } +} + +func TestAddress_AddrForKey(t *testing.T) { + publicKey := ed25519.PublicKey{ + 189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86, + 251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251, + } + + expectedAddress := Address{ + 2, 0, 132, 138, 96, 79, 187, 126, 67, 132, 101, 219, 141, 182, 104, 149, + } + + if *AddrForKey(publicKey) != expectedAddress { + t.Fatal("invalid address returned") + } +} + +func TestAddress_SubnetForKey(t *testing.T) { + publicKey := ed25519.PublicKey{ + 189, 186, 207, 216, 34, 64, 222, 61, 205, 18, 57, 36, 203, 181, 82, 86, + 251, 141, 171, 8, 170, 152, 227, 5, 82, 138, 184, 79, 65, 158, 110, 251, + } + + expectedSubnet := Subnet{3, 0, 132, 138, 96, 79, 187, 126} + + if *SubnetForKey(publicKey) != expectedSubnet { + t.Fatal("invalid subnet returned") + } +} + +func TestAddress_Address_GetKey(t *testing.T) { + address := Address{ + 2, 0, 132, 138, 96, 79, 187, 126, 67, 132, 101, 219, 141, 182, 104, 149, + } + + expectedPublicKey := ed25519.PublicKey{ + 189, 186, 207, 216, 34, 64, 222, 61, + 205, 18, 57, 36, 203, 181, 127, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + } + + if !bytes.Equal(address.GetKey(), expectedPublicKey) { + t.Fatal("invalid public key returned") + } +} + +func TestAddress_Subnet_GetKey(t *testing.T) { + subnet := Subnet{3, 0, 132, 138, 96, 79, 187, 126} + + expectedPublicKey := ed25519.PublicKey{ + 189, 186, 207, 216, 34, 64, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + 255, 255, 255, 255, 255, 255, 255, 255, + } + + if !bytes.Equal(subnet.GetKey(), expectedPublicKey) { + t.Fatal("invalid public key returned") + } +} diff --git a/src/config/config_test.go b/src/config/config_test.go new file mode 100644 index 00000000..8b6e14e1 --- /dev/null +++ b/src/config/config_test.go @@ -0,0 +1,54 @@ +package config + +import ( + "bytes" + "encoding/hex" + "testing" +) + +func TestConfig_Keys(t *testing.T) { + var nodeConfig NodeConfig + nodeConfig.NewKeys() + + publicKey1, err := hex.DecodeString(nodeConfig.PublicKey) + + if err != nil { + t.Fatal("can not decode generated public key") + } + + if len(publicKey1) == 0 { + t.Fatal("empty public key generated") + } + + privateKey1, err := hex.DecodeString(nodeConfig.PrivateKey) + + if err != nil { + t.Fatal("can not decode generated private key") + } + + if len(privateKey1) == 0 { + t.Fatal("empty private key generated") + } + + nodeConfig.NewKeys() + + publicKey2, err := hex.DecodeString(nodeConfig.PublicKey) + + if err != nil { + t.Fatal("can not decode generated public key") + } + + if bytes.Equal(publicKey2, publicKey1) { + t.Fatal("same public key generated") + } + + privateKey2, err := hex.DecodeString(nodeConfig.PrivateKey) + + if err != nil { + t.Fatal("can not decode generated private key") + } + + if bytes.Equal(privateKey2, privateKey1) { + t.Fatal("same private key generated") + } +} From 408d381591e99c273bf8db520a185478cdd8024f Mon Sep 17 00:00:00 2001 From: Neil Alexander Date: Mon, 6 Dec 2021 11:19:58 +0000 Subject: [PATCH 033/334] Set `hostArchitectures` in macOS `.pkg` installer --- contrib/macos/create-pkg.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/contrib/macos/create-pkg.sh b/contrib/macos/create-pkg.sh index 919c45ed..773f01ee 100755 --- a/contrib/macos/create-pkg.sh +++ b/contrib/macos/create-pkg.sh @@ -79,6 +79,7 @@ PKGNAME=$(sh contrib/semver/name.sh) PKGVERSION=$(sh contrib/semver/version.sh --bare) PKGARCH=${PKGARCH-amd64} PAYLOADSIZE=$(( $(wc -c pkgbuild/flat/base.pkg/Payload | awk '{ print $1 }') / 1024 )) +[ "$PKGARCH" = "amd64" ] && PKGHOSTARCH="x86_64" || PKGHOSTARCH=${PKGARCH} # Create the PackageInfo file cat > pkgbuild/flat/base.pkg/PackageInfo << EOF @@ -98,7 +99,7 @@ cat > pkgbuild/flat/Distribution << EOF Yggdrasil (${PKGNAME}-${PKGVERSION}) - +