mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	
						commit
						a7da93ffd8
					
				
					 19 changed files with 105 additions and 154 deletions
				
			
		| 
						 | 
					@ -35,7 +35,7 @@ import (
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type node struct {
 | 
					type node struct {
 | 
				
			||||||
	core      core.Core
 | 
						core      core.Core
 | 
				
			||||||
	state     *config.NodeState
 | 
						config    *config.NodeConfig
 | 
				
			||||||
	tuntap    module.Module // tuntap.TunAdapter
 | 
						tuntap    module.Module // tuntap.TunAdapter
 | 
				
			||||||
	multicast module.Module // multicast.Multicast
 | 
						multicast module.Module // multicast.Multicast
 | 
				
			||||||
	admin     module.Module // admin.AdminSocket
 | 
						admin     module.Module // admin.AdminSocket
 | 
				
			||||||
| 
						 | 
					@ -107,7 +107,9 @@ func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	json.Unmarshal(confJson, &cfg)
 | 
						if err := json.Unmarshal(confJson, &cfg); err != nil {
 | 
				
			||||||
 | 
							panic(err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	// Overlay our newly mapped configuration onto the autoconf node config that
 | 
						// Overlay our newly mapped configuration onto the autoconf node config that
 | 
				
			||||||
	// we generated above.
 | 
						// we generated above.
 | 
				
			||||||
	if err = mapstructure.Decode(dat, &cfg); err != nil {
 | 
						if err = mapstructure.Decode(dat, &cfg); err != nil {
 | 
				
			||||||
| 
						 | 
					@ -272,8 +274,7 @@ func main() {
 | 
				
			||||||
	n := node{}
 | 
						n := node{}
 | 
				
			||||||
	// Now start Yggdrasil - this starts the DHT, router, switch and other core
 | 
						// Now start Yggdrasil - this starts the DHT, router, switch and other core
 | 
				
			||||||
	// components needed for Yggdrasil to operate
 | 
						// components needed for Yggdrasil to operate
 | 
				
			||||||
	n.state, err = n.core.Start(cfg, logger)
 | 
						if err = n.core.Start(cfg, logger); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		logger.Errorln("An error occurred during startup")
 | 
							logger.Errorln("An error occurred during startup")
 | 
				
			||||||
		panic(err)
 | 
							panic(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -284,20 +285,23 @@ func main() {
 | 
				
			||||||
	n.tuntap = &tuntap.TunAdapter{}
 | 
						n.tuntap = &tuntap.TunAdapter{}
 | 
				
			||||||
	n.tuntap.(*tuntap.TunAdapter).SetSessionGatekeeper(n.sessionFirewall)
 | 
						n.tuntap.(*tuntap.TunAdapter).SetSessionGatekeeper(n.sessionFirewall)
 | 
				
			||||||
	// Start the admin socket
 | 
						// Start the admin socket
 | 
				
			||||||
	n.admin.Init(&n.core, n.state, logger, nil)
 | 
						if err := n.admin.Init(&n.core, cfg, logger, nil); err != nil {
 | 
				
			||||||
	if err := n.admin.Start(); err != nil {
 | 
							logger.Errorln("An error occured initialising admin socket:", err)
 | 
				
			||||||
 | 
						} else if err := n.admin.Start(); err != nil {
 | 
				
			||||||
		logger.Errorln("An error occurred starting admin socket:", err)
 | 
							logger.Errorln("An error occurred starting admin socket:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	n.admin.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
						n.admin.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
				
			||||||
	// Start the multicast interface
 | 
						// Start the multicast interface
 | 
				
			||||||
	n.multicast.Init(&n.core, n.state, logger, nil)
 | 
						if err := n.multicast.Init(&n.core, cfg, logger, nil); err != nil {
 | 
				
			||||||
	if err := n.multicast.Start(); err != nil {
 | 
							logger.Errorln("An error occured initialising multicast:", err)
 | 
				
			||||||
 | 
						} else if err := n.multicast.Start(); err != nil {
 | 
				
			||||||
		logger.Errorln("An error occurred starting multicast:", err)
 | 
							logger.Errorln("An error occurred starting multicast:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	n.multicast.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
						n.multicast.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
				
			||||||
	// Start the TUN/TAP interface
 | 
						// Start the TUN/TAP interface
 | 
				
			||||||
	n.tuntap.Init(&n.core, n.state, logger, nil)
 | 
						if err := n.tuntap.Init(&n.core, cfg, logger, nil); err != nil {
 | 
				
			||||||
	if err := n.tuntap.Start(); 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)
 | 
							logger.Errorln("An error occurred starting TUN/TAP:", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
						n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
				
			||||||
| 
						 | 
					@ -317,23 +321,23 @@ func main() {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *node) shutdown() {
 | 
					func (n *node) shutdown() {
 | 
				
			||||||
	n.admin.Stop()
 | 
						_ = n.admin.Stop()
 | 
				
			||||||
	n.multicast.Stop()
 | 
						_ = n.multicast.Stop()
 | 
				
			||||||
	n.tuntap.Stop()
 | 
						_ = n.tuntap.Stop()
 | 
				
			||||||
	n.core.Stop()
 | 
						n.core.Stop()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
 | 
					func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
 | 
				
			||||||
	n.state.Mutex.RLock()
 | 
						n.config.RLock()
 | 
				
			||||||
	defer n.state.Mutex.RUnlock()
 | 
						defer n.config.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow by default if the session firewall is disabled
 | 
						// Allow by default if the session firewall is disabled
 | 
				
			||||||
	if !n.state.Current.SessionFirewall.Enable {
 | 
						if !n.config.SessionFirewall.Enable {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Reject blacklisted nodes
 | 
						// Reject blacklisted nodes
 | 
				
			||||||
	for _, b := range n.state.Current.SessionFirewall.BlacklistPublicKeys {
 | 
						for _, b := range n.config.SessionFirewall.BlacklistPublicKeys {
 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			if bytes.Equal(key, pubkey) {
 | 
								if bytes.Equal(key, pubkey) {
 | 
				
			||||||
| 
						 | 
					@ -343,7 +347,7 @@ func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow whitelisted nodes
 | 
						// Allow whitelisted nodes
 | 
				
			||||||
	for _, b := range n.state.Current.SessionFirewall.WhitelistPublicKeys {
 | 
						for _, b := range n.config.SessionFirewall.WhitelistPublicKeys {
 | 
				
			||||||
		key, err := hex.DecodeString(b)
 | 
							key, err := hex.DecodeString(b)
 | 
				
			||||||
		if err == nil {
 | 
							if err == nil {
 | 
				
			||||||
			if bytes.Equal(key, pubkey) {
 | 
								if bytes.Equal(key, pubkey) {
 | 
				
			||||||
| 
						 | 
					@ -353,7 +357,7 @@ func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow outbound sessions if appropriate
 | 
						// Allow outbound sessions if appropriate
 | 
				
			||||||
	if n.state.Current.SessionFirewall.AlwaysAllowOutbound {
 | 
						if n.config.SessionFirewall.AlwaysAllowOutbound {
 | 
				
			||||||
		if initiator {
 | 
							if initiator {
 | 
				
			||||||
			return true
 | 
								return true
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					@ -369,12 +373,12 @@ func (n *node) sessionFirewall(pubkey ed25519.PublicKey, initiator bool) bool {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow direct peers if appropriate
 | 
						// Allow direct peers if appropriate
 | 
				
			||||||
	if n.state.Current.SessionFirewall.AllowFromDirect && isDirectPeer {
 | 
						if n.config.SessionFirewall.AllowFromDirect && isDirectPeer {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Allow remote nodes if appropriate
 | 
						// Allow remote nodes if appropriate
 | 
				
			||||||
	if n.state.Current.SessionFirewall.AllowFromRemote && !isDirectPeer {
 | 
						if n.config.SessionFirewall.AllowFromRemote && !isDirectPeer {
 | 
				
			||||||
		return true
 | 
							return true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -47,8 +47,8 @@ func run() int {
 | 
				
			||||||
		fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n\n", os.Args[0])
 | 
							fmt.Fprintf(flag.CommandLine.Output(), "Usage: %s [options] command [key=value] [key=value] ...\n\n", os.Args[0])
 | 
				
			||||||
		fmt.Println("Options:")
 | 
							fmt.Println("Options:")
 | 
				
			||||||
		flag.PrintDefaults()
 | 
							flag.PrintDefaults()
 | 
				
			||||||
		fmt.Println("\nPlease note that options must always specified BEFORE the command\non the command line or they will be ignored.\n")
 | 
							fmt.Println("\nPlease note that options must always specified BEFORE the command\non the command line or they will be ignored.\n") // nolint:govet
 | 
				
			||||||
		fmt.Println("Commands:\n  - Use \"list\" for a list of available commands\n")
 | 
							fmt.Println("Commands:\n  - Use \"list\" for a list of available commands\n")                                                      // nolint:govet
 | 
				
			||||||
		fmt.Println("Examples:")
 | 
							fmt.Println("Examples:")
 | 
				
			||||||
		fmt.Println("  - ", os.Args[0], "list")
 | 
							fmt.Println("  - ", os.Args[0], "list")
 | 
				
			||||||
		fmt.Println("  - ", os.Args[0], "getPeers")
 | 
							fmt.Println("  - ", os.Args[0], "getPeers")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -63,12 +63,13 @@ func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(js
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Init runs the initial admin setup.
 | 
					// Init runs the initial admin setup.
 | 
				
			||||||
func (a *AdminSocket) Init(c *core.Core, state *config.NodeState, log *log.Logger, options interface{}) error {
 | 
					func (a *AdminSocket) Init(c *core.Core, nc *config.NodeConfig, log *log.Logger, options interface{}) error {
 | 
				
			||||||
	a.core = c
 | 
						a.core = c
 | 
				
			||||||
	a.log = log
 | 
						a.log = log
 | 
				
			||||||
	a.handlers = make(map[string]handler)
 | 
						a.handlers = make(map[string]handler)
 | 
				
			||||||
	current := state.GetCurrent()
 | 
						nc.RLock()
 | 
				
			||||||
	a.listenaddr = current.AdminListen
 | 
						a.listenaddr = nc.AdminListen
 | 
				
			||||||
 | 
						nc.RUnlock()
 | 
				
			||||||
	a.done = make(chan struct{})
 | 
						a.done = make(chan struct{})
 | 
				
			||||||
	close(a.done) // Start in a done / not-started state
 | 
						close(a.done) // Start in a done / not-started state
 | 
				
			||||||
	_ = a.AddHandler("list", []string{}, func(_ json.RawMessage) (interface{}, error) {
 | 
						_ = a.AddHandler("list", []string{}, func(_ json.RawMessage) (interface{}, error) {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -24,41 +24,11 @@ import (
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/defaults"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NodeState represents the active and previous configuration of an Yggdrasil
 | 
					 | 
				
			||||||
// node. A NodeState object is returned when starting an Yggdrasil node. Note
 | 
					 | 
				
			||||||
// that this structure and related functions are likely to disappear soon.
 | 
					 | 
				
			||||||
type NodeState struct {
 | 
					 | 
				
			||||||
	Current  NodeConfig
 | 
					 | 
				
			||||||
	Previous NodeConfig
 | 
					 | 
				
			||||||
	Mutex    sync.RWMutex
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Current returns the active node configuration.
 | 
					 | 
				
			||||||
func (s *NodeState) GetCurrent() NodeConfig {
 | 
					 | 
				
			||||||
	s.Mutex.RLock()
 | 
					 | 
				
			||||||
	defer s.Mutex.RUnlock()
 | 
					 | 
				
			||||||
	return s.Current
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Previous returns the previous node configuration.
 | 
					 | 
				
			||||||
func (s *NodeState) GetPrevious() NodeConfig {
 | 
					 | 
				
			||||||
	s.Mutex.RLock()
 | 
					 | 
				
			||||||
	defer s.Mutex.RUnlock()
 | 
					 | 
				
			||||||
	return s.Previous
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// Replace the node configuration with new configuration.
 | 
					 | 
				
			||||||
func (s *NodeState) Replace(n NodeConfig) {
 | 
					 | 
				
			||||||
	s.Mutex.Lock()
 | 
					 | 
				
			||||||
	defer s.Mutex.Unlock()
 | 
					 | 
				
			||||||
	s.Previous = s.Current
 | 
					 | 
				
			||||||
	s.Current = n
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// NodeConfig is the main configuration structure, containing configuration
 | 
					// NodeConfig is the main configuration structure, containing configuration
 | 
				
			||||||
// options that are necessary for an Yggdrasil node to run. You will need to
 | 
					// options that are necessary for an Yggdrasil node to run. You will need to
 | 
				
			||||||
// supply one of these structs to the Yggdrasil core when starting a node.
 | 
					// supply one of these structs to the Yggdrasil core when starting a node.
 | 
				
			||||||
type NodeConfig struct {
 | 
					type NodeConfig struct {
 | 
				
			||||||
 | 
						sync.RWMutex
 | 
				
			||||||
	Peers               []string               `comment:"List of connection strings for outbound peer connections in URI format,\ne.g. tcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. These connections\nwill obey the operating system routing table, therefore you should\nuse this section when you may connect via different interfaces."`
 | 
						Peers               []string               `comment:"List of connection strings for outbound peer connections in URI format,\ne.g. tcp://a.b.c.d:e or socks://a.b.c.d:e/f.g.h.i:j. These connections\nwill obey the operating system routing table, therefore you should\nuse this section when you may connect via different interfaces."`
 | 
				
			||||||
	InterfacePeers      map[string][]string    `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ tcp://a.b.c.d:e ] }.\nNote that SOCKS peerings will NOT be affected by this option and should\ngo in the \"Peers\" section instead."`
 | 
						InterfacePeers      map[string][]string    `comment:"List of connection strings for outbound peer connections in URI format,\narranged by source interface, e.g. { \"eth0\": [ tcp://a.b.c.d:e ] }.\nNote that SOCKS peerings will NOT be affected by this option and should\ngo in the \"Peers\" section instead."`
 | 
				
			||||||
	Listen              []string               `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntcp://0.0.0.0:0 or tcp://[::]:0 to listen on all interfaces."`
 | 
						Listen              []string               `comment:"Listen addresses for incoming connections. You will need to add\nlisteners in order to accept incoming peerings from non-local nodes.\nMulticast peer discovery will work regardless of any listeners set\nhere. Each listener should be specified in URI format as above, e.g.\ntcp://0.0.0.0:0 or tcp://[::]:0 to listen on all interfaces."`
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,7 +25,7 @@ type Core struct {
 | 
				
			||||||
	// guarantee that it will be covered by the mutex
 | 
						// guarantee that it will be covered by the mutex
 | 
				
			||||||
	phony.Inbox
 | 
						phony.Inbox
 | 
				
			||||||
	*iw.PacketConn
 | 
						*iw.PacketConn
 | 
				
			||||||
	config       config.NodeState // Config
 | 
						config       *config.NodeConfig // Config
 | 
				
			||||||
	secret       ed25519.PrivateKey
 | 
						secret       ed25519.PrivateKey
 | 
				
			||||||
	public       ed25519.PublicKey
 | 
						public       ed25519.PublicKey
 | 
				
			||||||
	links        links
 | 
						links        links
 | 
				
			||||||
| 
						 | 
					@ -42,9 +42,9 @@ func (c *Core) _init() error {
 | 
				
			||||||
		c.log = log.New(ioutil.Discard, "", 0)
 | 
							c.log = log.New(ioutil.Discard, "", 0)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	current := c.config.GetCurrent()
 | 
						c.config.RLock()
 | 
				
			||||||
 | 
						sigPriv, err := hex.DecodeString(c.config.PrivateKey)
 | 
				
			||||||
	sigPriv, err := hex.DecodeString(current.PrivateKey)
 | 
						c.config.RUnlock()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -64,11 +64,11 @@ func (c *Core) _init() error {
 | 
				
			||||||
// configure them. The loop ensures that disconnected peers will eventually
 | 
					// configure them. The loop ensures that disconnected peers will eventually
 | 
				
			||||||
// be reconnected with.
 | 
					// be reconnected with.
 | 
				
			||||||
func (c *Core) _addPeerLoop() {
 | 
					func (c *Core) _addPeerLoop() {
 | 
				
			||||||
	// Get the peers from the config - these could change!
 | 
						c.config.RLock()
 | 
				
			||||||
	current := c.config.GetCurrent()
 | 
						defer c.config.RUnlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add peers from the Peers section
 | 
						// Add peers from the Peers section
 | 
				
			||||||
	for _, peer := range current.Peers {
 | 
						for _, peer := range c.config.Peers {
 | 
				
			||||||
		go func(peer string, intf string) {
 | 
							go func(peer string, intf string) {
 | 
				
			||||||
			u, err := url.Parse(peer)
 | 
								u, err := url.Parse(peer)
 | 
				
			||||||
			if err != nil {
 | 
								if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -81,7 +81,7 @@ func (c *Core) _addPeerLoop() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Add peers from the InterfacePeers section
 | 
						// Add peers from the InterfacePeers section
 | 
				
			||||||
	for intf, intfpeers := range current.InterfacePeers {
 | 
						for intf, intfpeers := range c.config.InterfacePeers {
 | 
				
			||||||
		for _, peer := range intfpeers {
 | 
							for _, peer := range intfpeers {
 | 
				
			||||||
			go func(peer string, intf string) {
 | 
								go func(peer string, intf string) {
 | 
				
			||||||
				u, err := url.Parse(peer)
 | 
									u, err := url.Parse(peer)
 | 
				
			||||||
| 
						 | 
					@ -107,21 +107,17 @@ func (c *Core) _addPeerLoop() {
 | 
				
			||||||
// TCP and UDP sockets, a multicast discovery socket, an admin socket, router,
 | 
					// TCP and UDP sockets, a multicast discovery socket, an admin socket, router,
 | 
				
			||||||
// switch and DHT node. A config.NodeState is returned which contains both the
 | 
					// switch and DHT node. A config.NodeState is returned which contains both the
 | 
				
			||||||
// current and previous configurations (from reconfigures).
 | 
					// current and previous configurations (from reconfigures).
 | 
				
			||||||
func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) (conf *config.NodeState, err error) {
 | 
					func (c *Core) Start(nc *config.NodeConfig, log *log.Logger) (err error) {
 | 
				
			||||||
	phony.Block(c, func() {
 | 
						phony.Block(c, func() {
 | 
				
			||||||
		conf, err = c._start(nc, log)
 | 
							err = c._start(nc, log)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
	return
 | 
						return
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// This function is unsafe and should only be ran by the core actor.
 | 
					// This function is unsafe and should only be ran by the core actor.
 | 
				
			||||||
func (c *Core) _start(nc *config.NodeConfig, log *log.Logger) (*config.NodeState, error) {
 | 
					func (c *Core) _start(nc *config.NodeConfig, log *log.Logger) error {
 | 
				
			||||||
	c.log = log
 | 
						c.log = log
 | 
				
			||||||
 | 
						c.config = nc
 | 
				
			||||||
	c.config = config.NodeState{
 | 
					 | 
				
			||||||
		Current:  *nc,
 | 
					 | 
				
			||||||
		Previous: *nc,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if name := version.BuildName(); name != "unknown" {
 | 
						if name := version.BuildName(); name != "unknown" {
 | 
				
			||||||
		c.log.Infoln("Build name:", name)
 | 
							c.log.Infoln("Build name:", name)
 | 
				
			||||||
| 
						 | 
					@ -133,30 +129,20 @@ func (c *Core) _start(nc *config.NodeConfig, log *log.Logger) (*config.NodeState
 | 
				
			||||||
	c.log.Infoln("Starting up...")
 | 
						c.log.Infoln("Starting up...")
 | 
				
			||||||
	if err := c._init(); err != nil {
 | 
						if err := c._init(); err != nil {
 | 
				
			||||||
		c.log.Errorln("Failed to initialize core")
 | 
							c.log.Errorln("Failed to initialize core")
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := c.links.init(c); err != nil {
 | 
						if err := c.links.init(c); err != nil {
 | 
				
			||||||
		c.log.Errorln("Failed to start link interfaces")
 | 
							c.log.Errorln("Failed to start link interfaces")
 | 
				
			||||||
		return nil, err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	//if err := c.switchTable.start(); err != nil {
 | 
					 | 
				
			||||||
	//	c.log.Errorln("Failed to start switch")
 | 
					 | 
				
			||||||
	//	return nil, err
 | 
					 | 
				
			||||||
	//}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	//if err := c.router.start(); err != nil {
 | 
					 | 
				
			||||||
	//	c.log.Errorln("Failed to start router")
 | 
					 | 
				
			||||||
	//	return nil, err
 | 
					 | 
				
			||||||
	//}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	c.addPeerTimer = time.AfterFunc(0, func() {
 | 
						c.addPeerTimer = time.AfterFunc(0, func() {
 | 
				
			||||||
		c.Act(nil, c._addPeerLoop)
 | 
							c.Act(nil, c._addPeerLoop)
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	c.log.Infoln("Startup complete")
 | 
						c.log.Infoln("Startup complete")
 | 
				
			||||||
	return &c.config, nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Stop shuts down the Yggdrasil node.
 | 
					// Stop shuts down the Yggdrasil node.
 | 
				
			||||||
| 
						 | 
					@ -172,7 +158,7 @@ func (c *Core) _stop() {
 | 
				
			||||||
		c.addPeerTimer.Stop()
 | 
							c.addPeerTimer.Stop()
 | 
				
			||||||
		c.addPeerTimer = nil
 | 
							c.addPeerTimer = nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	c.links.stop()
 | 
						_ = c.links.stop()
 | 
				
			||||||
	/* FIXME this deadlocks, need a waitgroup or something to coordinate shutdown
 | 
						/* FIXME this deadlocks, need a waitgroup or something to coordinate shutdown
 | 
				
			||||||
	for _, peer := range c.GetPeers() {
 | 
						for _, peer := range c.GetPeers() {
 | 
				
			||||||
		c.DisconnectPeer(peer.Port)
 | 
							c.DisconnectPeer(peer.Port)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,14 +40,12 @@ func GetLoggerWithPrefix(prefix string, verbose bool) *log.Logger {
 | 
				
			||||||
// Verbosity flag is passed to logger.
 | 
					// Verbosity flag is passed to logger.
 | 
				
			||||||
func CreateAndConnectTwo(t testing.TB, verbose bool) (nodeA *Core, nodeB *Core) {
 | 
					func CreateAndConnectTwo(t testing.TB, verbose bool) (nodeA *Core, nodeB *Core) {
 | 
				
			||||||
	nodeA = new(Core)
 | 
						nodeA = new(Core)
 | 
				
			||||||
	_, err := nodeA.Start(GenerateConfig(), GetLoggerWithPrefix("A: ", verbose))
 | 
						if err := nodeA.Start(GenerateConfig(), GetLoggerWithPrefix("A: ", verbose)); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	nodeB = new(Core)
 | 
						nodeB = new(Core)
 | 
				
			||||||
	_, err = nodeB.Start(GenerateConfig(), GetLoggerWithPrefix("B: ", verbose))
 | 
						if err := nodeB.Start(GenerateConfig(), GetLoggerWithPrefix("B: ", verbose)); err != nil {
 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		t.Fatal(err)
 | 
							t.Fatal(err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -188,7 +188,9 @@ func (intf *link) handler() (chan struct{}, error) {
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Check if we're authorized to connect to this key / IP
 | 
						// Check if we're authorized to connect to this key / IP
 | 
				
			||||||
	allowed := intf.links.core.config.GetCurrent().AllowedPublicKeys
 | 
						intf.links.core.config.RLock()
 | 
				
			||||||
 | 
						allowed := intf.links.core.config.AllowedPublicKeys
 | 
				
			||||||
 | 
						intf.links.core.config.RUnlock()
 | 
				
			||||||
	isallowed := len(allowed) == 0
 | 
						isallowed := len(allowed) == 0
 | 
				
			||||||
	for _, k := range allowed {
 | 
						for _, k := range allowed {
 | 
				
			||||||
		if k == hex.EncodeToString(meta.key) { // TODO: this is yuck
 | 
							if k == hex.EncodeToString(meta.key) { // TODO: this is yuck
 | 
				
			||||||
| 
						 | 
					@ -248,15 +250,3 @@ func (intf *link) close() {
 | 
				
			||||||
func (intf *link) name() string {
 | 
					func (intf *link) name() string {
 | 
				
			||||||
	return intf.lname
 | 
						return intf.lname
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					 | 
				
			||||||
func (intf *link) local() string {
 | 
					 | 
				
			||||||
	return intf.info.local
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (intf *link) remote() string {
 | 
					 | 
				
			||||||
	return intf.info.remote
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (intf *link) interfaceType() string {
 | 
					 | 
				
			||||||
	return intf.info.linkType
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -67,7 +67,7 @@ type tcpOptions struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (l *TcpListener) Stop() {
 | 
					func (l *TcpListener) Stop() {
 | 
				
			||||||
	defer func() { recover() }()
 | 
						defer func() { _ = recover() }()
 | 
				
			||||||
	close(l.stop)
 | 
						close(l.stop)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -75,7 +75,7 @@ func (l *TcpListener) Stop() {
 | 
				
			||||||
func (t *tcp) setExtraOptions(c net.Conn) {
 | 
					func (t *tcp) setExtraOptions(c net.Conn) {
 | 
				
			||||||
	switch sock := c.(type) {
 | 
						switch sock := c.(type) {
 | 
				
			||||||
	case *net.TCPConn:
 | 
						case *net.TCPConn:
 | 
				
			||||||
		sock.SetNoDelay(true)
 | 
							_ = sock.SetNoDelay(true)
 | 
				
			||||||
	// TODO something for socks5
 | 
						// TODO something for socks5
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -104,9 +104,9 @@ func (t *tcp) init(l *links) error {
 | 
				
			||||||
	t.listeners = make(map[string]*TcpListener)
 | 
						t.listeners = make(map[string]*TcpListener)
 | 
				
			||||||
	t.mutex.Unlock()
 | 
						t.mutex.Unlock()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	t.links.core.config.Mutex.RLock()
 | 
						t.links.core.config.RLock()
 | 
				
			||||||
	defer t.links.core.config.Mutex.RUnlock()
 | 
						defer t.links.core.config.RUnlock()
 | 
				
			||||||
	for _, listenaddr := range t.links.core.config.Current.Listen {
 | 
						for _, listenaddr := range t.links.core.config.Listen {
 | 
				
			||||||
		u, err := url.Parse(listenaddr)
 | 
							u, err := url.Parse(listenaddr)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.links.core.log.Errorln("Failed to parse listener: listener", listenaddr, "is not correctly formatted, ignoring")
 | 
								t.links.core.log.Errorln("Failed to parse listener: listener", listenaddr, "is not correctly formatted, ignoring")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -36,7 +36,7 @@ func (t *tcp) getControl(sintf string) func(string, string, syscall.RawConn) err
 | 
				
			||||||
		btd := func(fd uintptr) {
 | 
							btd := func(fd uintptr) {
 | 
				
			||||||
			err = unix.BindToDevice(int(fd), sintf)
 | 
								err = unix.BindToDevice(int(fd), sintf)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		c.Control(btd)
 | 
							_ = c.Control(btd)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			t.links.core.log.Debugln("Failed to set SO_BINDTODEVICE:", sintf)
 | 
								t.links.core.log.Debugln("Failed to set SO_BINDTODEVICE:", sintf)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -11,7 +11,7 @@ import (
 | 
				
			||||||
// Module is an interface that defines which functions must be supported by a
 | 
					// Module is an interface that defines which functions must be supported by a
 | 
				
			||||||
// given Yggdrasil module.
 | 
					// given Yggdrasil module.
 | 
				
			||||||
type Module interface {
 | 
					type Module interface {
 | 
				
			||||||
	Init(core *core.Core, state *config.NodeState, log *log.Logger, options interface{}) error
 | 
						Init(core *core.Core, state *config.NodeConfig, log *log.Logger, options interface{}) error
 | 
				
			||||||
	Start() error
 | 
						Start() error
 | 
				
			||||||
	Stop() error
 | 
						Stop() error
 | 
				
			||||||
	SetupAdminHandlers(a *admin.AdminSocket)
 | 
						SetupAdminHandlers(a *admin.AdminSocket)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -23,7 +23,7 @@ import (
 | 
				
			||||||
type Multicast struct {
 | 
					type Multicast struct {
 | 
				
			||||||
	phony.Inbox
 | 
						phony.Inbox
 | 
				
			||||||
	core        *core.Core
 | 
						core        *core.Core
 | 
				
			||||||
	config      *config.NodeState
 | 
						config      *config.NodeConfig
 | 
				
			||||||
	log         *log.Logger
 | 
						log         *log.Logger
 | 
				
			||||||
	sock        *ipv6.PacketConn
 | 
						sock        *ipv6.PacketConn
 | 
				
			||||||
	groupAddr   string
 | 
						groupAddr   string
 | 
				
			||||||
| 
						 | 
					@ -45,14 +45,13 @@ type listenerInfo struct {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Init prepares the multicast interface for use.
 | 
					// Init prepares the multicast interface for use.
 | 
				
			||||||
func (m *Multicast) Init(core *core.Core, state *config.NodeState, log *log.Logger, options interface{}) error {
 | 
					func (m *Multicast) Init(core *core.Core, nc *config.NodeConfig, log *log.Logger, options interface{}) error {
 | 
				
			||||||
	m.core = core
 | 
						m.core = core
 | 
				
			||||||
	m.config = state
 | 
						m.config = nc
 | 
				
			||||||
	m.log = log
 | 
						m.log = log
 | 
				
			||||||
	m.listeners = make(map[string]*listenerInfo)
 | 
						m.listeners = make(map[string]*listenerInfo)
 | 
				
			||||||
	m._interfaces = make(map[string]interfaceInfo)
 | 
						m._interfaces = make(map[string]interfaceInfo)
 | 
				
			||||||
	current := m.config.GetCurrent()
 | 
						m.listenPort = m.config.LinkLocalTCPPort
 | 
				
			||||||
	m.listenPort = current.LinkLocalTCPPort
 | 
					 | 
				
			||||||
	m.groupAddr = "[ff02::114]:9001"
 | 
						m.groupAddr = "[ff02::114]:9001"
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -73,7 +72,9 @@ func (m *Multicast) _start() error {
 | 
				
			||||||
	if m.isOpen {
 | 
						if m.isOpen {
 | 
				
			||||||
		return fmt.Errorf("multicast module is already started")
 | 
							return fmt.Errorf("multicast module is already started")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if len(m.config.GetCurrent().MulticastInterfaces) == 0 {
 | 
						m.config.RLock()
 | 
				
			||||||
 | 
						defer m.config.RUnlock()
 | 
				
			||||||
 | 
						if len(m.config.MulticastInterfaces) == 0 {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m.log.Infoln("Starting multicast module")
 | 
						m.log.Infoln("Starting multicast module")
 | 
				
			||||||
| 
						 | 
					@ -90,7 +91,7 @@ func (m *Multicast) _start() error {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m.sock = ipv6.NewPacketConn(conn)
 | 
						m.sock = ipv6.NewPacketConn(conn)
 | 
				
			||||||
	if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil {
 | 
						if err = m.sock.SetControlMessage(ipv6.FlagDst, true); err != nil { // nolint:staticcheck
 | 
				
			||||||
		// Windows can't set this flag, so we need to handle it in other ways
 | 
							// Windows can't set this flag, so we need to handle it in other ways
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -161,8 +162,7 @@ func (m *Multicast) Interfaces() map[string]net.Interface {
 | 
				
			||||||
func (m *Multicast) getAllowedInterfaces() map[string]net.Interface {
 | 
					func (m *Multicast) getAllowedInterfaces() map[string]net.Interface {
 | 
				
			||||||
	interfaces := make(map[string]net.Interface)
 | 
						interfaces := make(map[string]net.Interface)
 | 
				
			||||||
	// Get interface expressions from config
 | 
						// Get interface expressions from config
 | 
				
			||||||
	current := m.config.GetCurrent()
 | 
						exprs := m.config.MulticastInterfaces
 | 
				
			||||||
	exprs := current.MulticastInterfaces
 | 
					 | 
				
			||||||
	// Ask the system for network interfaces
 | 
						// Ask the system for network interfaces
 | 
				
			||||||
	allifaces, err := net.Interfaces()
 | 
						allifaces, err := net.Interfaces()
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -269,7 +269,7 @@ func (m *Multicast) _announce() {
 | 
				
			||||||
				continue
 | 
									continue
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			// Join the multicast group
 | 
								// Join the multicast group
 | 
				
			||||||
			m.sock.JoinGroup(&iface, groupAddr)
 | 
								_ = m.sock.JoinGroup(&iface, groupAddr)
 | 
				
			||||||
			// Try and see if we already have a TCP listener for this interface
 | 
								// Try and see if we already have a TCP listener for this interface
 | 
				
			||||||
			var info *listenerInfo
 | 
								var info *listenerInfo
 | 
				
			||||||
			if nfo, ok := m.listeners[iface.Name]; !ok || nfo.listener.Listener == nil {
 | 
								if nfo, ok := m.listeners[iface.Name]; !ok || nfo.listener.Listener == nil {
 | 
				
			||||||
| 
						 | 
					@ -304,7 +304,7 @@ func (m *Multicast) _announce() {
 | 
				
			||||||
				a.Zone = ""
 | 
									a.Zone = ""
 | 
				
			||||||
				destAddr.Zone = iface.Name
 | 
									destAddr.Zone = iface.Name
 | 
				
			||||||
				msg := []byte(a.String())
 | 
									msg := []byte(a.String())
 | 
				
			||||||
				m.sock.WriteTo(msg, nil, destAddr)
 | 
									_, _ = m.sock.WriteTo(msg, nil, destAddr)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if info.interval.Seconds() < 15 {
 | 
								if info.interval.Seconds() < 15 {
 | 
				
			||||||
				info.interval += time.Second
 | 
									info.interval += time.Second
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -29,8 +29,6 @@ import (
 | 
				
			||||||
	"golang.org/x/sys/unix"
 | 
						"golang.org/x/sys/unix"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var awdlGoroutineStarted bool
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (m *Multicast) _multicastStarted() {
 | 
					func (m *Multicast) _multicastStarted() {
 | 
				
			||||||
	if !m.isOpen {
 | 
						if !m.isOpen {
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,16 +123,12 @@ func (tun *TunAdapter) write() {
 | 
				
			||||||
			continue // bad remote address/subnet
 | 
								continue // bad remote address/subnet
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		bs = buf[:TUN_OFFSET_BYTES+len(bs)]
 | 
							bs = buf[:TUN_OFFSET_BYTES+len(bs)]
 | 
				
			||||||
		n, err = tun.iface.Write(bs, TUN_OFFSET_BYTES)
 | 
							if _, err = tun.iface.Write(bs, TUN_OFFSET_BYTES); err != nil {
 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			tun.Act(nil, func() {
 | 
								tun.Act(nil, func() {
 | 
				
			||||||
				if !tun.isOpen {
 | 
									if !tun.isOpen {
 | 
				
			||||||
					tun.log.Errorln("TUN iface write error:", err)
 | 
										tun.log.Errorln("TUN iface write error:", err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if n != len(bs) {
 | 
					 | 
				
			||||||
			// TODO some kind of error reporting for a partial write
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -50,7 +50,7 @@ func (k *keyStore) sendToAddress(addr address.Address, bs []byte) {
 | 
				
			||||||
	if info := k.addrToInfo[addr]; info != nil {
 | 
						if info := k.addrToInfo[addr]; info != nil {
 | 
				
			||||||
		k.resetTimeout(info)
 | 
							k.resetTimeout(info)
 | 
				
			||||||
		k.mutex.Unlock()
 | 
							k.mutex.Unlock()
 | 
				
			||||||
		k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
							_, _ = k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		var buf *buffer
 | 
							var buf *buffer
 | 
				
			||||||
		if buf = k.addrBuffer[addr]; buf == nil {
 | 
							if buf = k.addrBuffer[addr]; buf == nil {
 | 
				
			||||||
| 
						 | 
					@ -79,7 +79,7 @@ func (k *keyStore) sendToSubnet(subnet address.Subnet, bs []byte) {
 | 
				
			||||||
	if info := k.subnetToInfo[subnet]; info != nil {
 | 
						if info := k.subnetToInfo[subnet]; info != nil {
 | 
				
			||||||
		k.resetTimeout(info)
 | 
							k.resetTimeout(info)
 | 
				
			||||||
		k.mutex.Unlock()
 | 
							k.mutex.Unlock()
 | 
				
			||||||
		k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
							_, _ = k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		var buf *buffer
 | 
							var buf *buffer
 | 
				
			||||||
		if buf = k.subnetBuffer[subnet]; buf == nil {
 | 
							if buf = k.subnetBuffer[subnet]; buf == nil {
 | 
				
			||||||
| 
						 | 
					@ -132,13 +132,13 @@ func (k *keyStore) update(key ed25519.PublicKey) *keyInfo {
 | 
				
			||||||
		k.mutex.Unlock()
 | 
							k.mutex.Unlock()
 | 
				
			||||||
		if buf := k.addrBuffer[info.address]; buf != nil {
 | 
							if buf := k.addrBuffer[info.address]; buf != nil {
 | 
				
			||||||
			for _, bs := range buf.packets {
 | 
								for _, bs := range buf.packets {
 | 
				
			||||||
				k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
									_, _ = k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			delete(k.addrBuffer, info.address)
 | 
								delete(k.addrBuffer, info.address)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if buf := k.subnetBuffer[info.subnet]; buf != nil {
 | 
							if buf := k.subnetBuffer[info.subnet]; buf != nil {
 | 
				
			||||||
			for _, bs := range buf.packets {
 | 
								for _, bs := range buf.packets {
 | 
				
			||||||
				k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
									_, _ = k.tun.core.WriteTo(bs, iwt.Addr(info.key[:]))
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			delete(k.subnetBuffer, info.subnet)
 | 
								delete(k.subnetBuffer, info.subnet)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -129,7 +129,7 @@ func (m *nodeinfo) _sendReq(key keyArray, callback func(nodeinfo NodeInfoPayload
 | 
				
			||||||
	if callback != nil {
 | 
						if callback != nil {
 | 
				
			||||||
		m._addCallback(key, callback)
 | 
							m._addCallback(key, callback)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	m.proto.tun.core.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:]))
 | 
						_, _ = m.proto.tun.core.WriteTo([]byte{typeSessionProto, typeProtoNodeInfoRequest}, iwt.Addr(key[:]))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (m *nodeinfo) handleReq(from phony.Actor, key keyArray) {
 | 
					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) {
 | 
					func (m *nodeinfo) _sendRes(key keyArray) {
 | 
				
			||||||
	bs := append([]byte{typeSessionProto, typeProtoNodeInfoResponse}, m._getNodeInfo()...)
 | 
						bs := append([]byte{typeSessionProto, typeProtoNodeInfoResponse}, m._getNodeInfo()...)
 | 
				
			||||||
	m.proto.tun.core.WriteTo(bs, iwt.Addr(key[:]))
 | 
						_, _ = m.proto.tun.core.WriteTo(bs, iwt.Addr(key[:]))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Admin socket stuff
 | 
					// Admin socket stuff
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -209,7 +209,7 @@ func (p *protoHandler) _handleGetDHTResponse(key keyArray, bs []byte) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) {
 | 
					func (p *protoHandler) _sendDebug(key keyArray, dType uint8, data []byte) {
 | 
				
			||||||
	bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...)
 | 
						bs := append([]byte{typeSessionProto, typeProtoDebug, dType}, data...)
 | 
				
			||||||
	p.tun.core.WriteTo(bs, iwt.Addr(key[:]))
 | 
						_, _ = p.tun.core.WriteTo(bs, iwt.Addr(key[:]))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Admin socket stuff
 | 
					// Admin socket stuff
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -35,7 +35,7 @@ type MTU uint16
 | 
				
			||||||
type TunAdapter struct {
 | 
					type TunAdapter struct {
 | 
				
			||||||
	core        *core.Core
 | 
						core        *core.Core
 | 
				
			||||||
	store       keyStore
 | 
						store       keyStore
 | 
				
			||||||
	config      *config.NodeState
 | 
						config      *config.NodeConfig
 | 
				
			||||||
	log         *log.Logger
 | 
						log         *log.Logger
 | 
				
			||||||
	addr        address.Address
 | 
						addr        address.Address
 | 
				
			||||||
	subnet      address.Subnet
 | 
						subnet      address.Subnet
 | 
				
			||||||
| 
						 | 
					@ -103,13 +103,17 @@ func MaximumMTU() uint64 {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Init initialises the TUN module. You must have acquired a Listener from
 | 
					// 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.
 | 
					// the Yggdrasil core before this point and it must not be in use elsewhere.
 | 
				
			||||||
func (tun *TunAdapter) Init(core *core.Core, config *config.NodeState, log *log.Logger, options interface{}) error {
 | 
					func (tun *TunAdapter) Init(core *core.Core, config *config.NodeConfig, log *log.Logger, options interface{}) error {
 | 
				
			||||||
	tun.core = core
 | 
						tun.core = core
 | 
				
			||||||
	tun.store.init(tun)
 | 
						tun.store.init(tun)
 | 
				
			||||||
	tun.config = config
 | 
						tun.config = config
 | 
				
			||||||
	tun.log = log
 | 
						tun.log = log
 | 
				
			||||||
	tun.proto.init(tun)
 | 
						tun.proto.init(tun)
 | 
				
			||||||
	tun.proto.nodeinfo.setNodeInfo(config.Current.NodeInfo, config.Current.NodeInfoPrivacy)
 | 
						tun.config.RLock()
 | 
				
			||||||
 | 
						if err := tun.proto.nodeinfo.setNodeInfo(tun.config.NodeInfo, tun.config.NodeInfoPrivacy); err != nil {
 | 
				
			||||||
 | 
							return fmt.Errorf("tun.proto.nodeinfo.setNodeInfo: %w", err)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						tun.config.RUnlock()
 | 
				
			||||||
	if err := tun.core.SetOutOfBandHandler(tun.oobHandler); err != nil {
 | 
						if err := tun.core.SetOutOfBandHandler(tun.oobHandler); err != nil {
 | 
				
			||||||
		return fmt.Errorf("tun.core.SetOutOfBandHander: %w", err)
 | 
							return fmt.Errorf("tun.core.SetOutOfBandHander: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -130,7 +134,8 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
	if tun.isOpen {
 | 
						if tun.isOpen {
 | 
				
			||||||
		return errors.New("TUN module is already started")
 | 
							return errors.New("TUN module is already started")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	current := tun.config.GetCurrent()
 | 
						tun.config.RLock()
 | 
				
			||||||
 | 
						defer tun.config.RUnlock()
 | 
				
			||||||
	if tun.config == nil {
 | 
						if tun.config == nil {
 | 
				
			||||||
		return errors.New("no configuration available to TUN")
 | 
							return errors.New("no configuration available to TUN")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					@ -139,21 +144,21 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
	tun.addr = *address.AddrForKey(pk)
 | 
						tun.addr = *address.AddrForKey(pk)
 | 
				
			||||||
	tun.subnet = *address.SubnetForKey(pk)
 | 
						tun.subnet = *address.SubnetForKey(pk)
 | 
				
			||||||
	addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1)
 | 
						addr := fmt.Sprintf("%s/%d", net.IP(tun.addr[:]).String(), 8*len(address.GetPrefix())-1)
 | 
				
			||||||
	if current.IfName == "none" || current.IfName == "dummy" {
 | 
						if tun.config.IfName == "none" || tun.config.IfName == "dummy" {
 | 
				
			||||||
		tun.log.Debugln("Not starting TUN as ifname is none or dummy")
 | 
							tun.log.Debugln("Not starting TUN as ifname is none or dummy")
 | 
				
			||||||
		tun.isEnabled = false
 | 
							tun.isEnabled = false
 | 
				
			||||||
		go tun.write()
 | 
							go tun.write()
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	mtu := current.IfMTU
 | 
						mtu := tun.config.IfMTU
 | 
				
			||||||
	if tun.maxSessionMTU() < mtu {
 | 
						if tun.maxSessionMTU() < mtu {
 | 
				
			||||||
		mtu = tun.maxSessionMTU()
 | 
							mtu = tun.maxSessionMTU()
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if err := tun.setup(current.IfName, addr, mtu); err != nil {
 | 
						if err := tun.setup(tun.config.IfName, addr, mtu); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if tun.MTU() != mtu {
 | 
						if tun.MTU() != mtu {
 | 
				
			||||||
		tun.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", current.IfMTU, tun.MTU(), MaximumMTU())
 | 
							tun.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", tun.config.IfMTU, tun.MTU(), MaximumMTU())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tun.isOpen = true
 | 
						tun.isOpen = true
 | 
				
			||||||
	tun.isEnabled = true
 | 
						tun.isEnabled = true
 | 
				
			||||||
| 
						 | 
					@ -216,13 +221,13 @@ func (tun *TunAdapter) oobHandler(fromKey, toKey ed25519.PublicKey, data []byte)
 | 
				
			||||||
func (tun *TunAdapter) sendKeyLookup(partial ed25519.PublicKey) {
 | 
					func (tun *TunAdapter) sendKeyLookup(partial ed25519.PublicKey) {
 | 
				
			||||||
	sig := ed25519.Sign(tun.core.PrivateKey(), partial[:])
 | 
						sig := ed25519.Sign(tun.core.PrivateKey(), partial[:])
 | 
				
			||||||
	bs := append([]byte{typeKeyLookup}, sig...)
 | 
						bs := append([]byte{typeKeyLookup}, sig...)
 | 
				
			||||||
	tun.core.SendOutOfBand(partial, bs)
 | 
						_ = tun.core.SendOutOfBand(partial, bs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) sendKeyResponse(dest ed25519.PublicKey) {
 | 
					func (tun *TunAdapter) sendKeyResponse(dest ed25519.PublicKey) {
 | 
				
			||||||
	sig := ed25519.Sign(tun.core.PrivateKey(), dest[:])
 | 
						sig := ed25519.Sign(tun.core.PrivateKey(), dest[:])
 | 
				
			||||||
	bs := append([]byte{typeKeyResponse}, sig...)
 | 
						bs := append([]byte{typeKeyResponse}, sig...)
 | 
				
			||||||
	tun.core.SendOutOfBand(dest, bs)
 | 
						_ = tun.core.SendOutOfBand(dest, bs)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) maxSessionMTU() uint64 {
 | 
					func (tun *TunAdapter) maxSessionMTU() uint64 {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,26 +40,29 @@ const (
 | 
				
			||||||
	darwin_ND6_INFINITE_LIFETIME = 0xFFFFFFFF // netinet6/nd6.h
 | 
						darwin_ND6_INFINITE_LIFETIME = 0xFFFFFFFF // netinet6/nd6.h
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nolint:structcheck
 | 
				
			||||||
type in6_addrlifetime struct {
 | 
					type in6_addrlifetime struct {
 | 
				
			||||||
	ia6t_expire    float64
 | 
						ia6t_expire    float64 // nolint:unused
 | 
				
			||||||
	ia6t_preferred float64
 | 
						ia6t_preferred float64 // nolint:unused
 | 
				
			||||||
	ia6t_vltime    uint32
 | 
						ia6t_vltime    uint32
 | 
				
			||||||
	ia6t_pltime    uint32
 | 
						ia6t_pltime    uint32
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nolint:structcheck
 | 
				
			||||||
type sockaddr_in6 struct {
 | 
					type sockaddr_in6 struct {
 | 
				
			||||||
	sin6_len      uint8
 | 
						sin6_len      uint8
 | 
				
			||||||
	sin6_family   uint8
 | 
						sin6_family   uint8
 | 
				
			||||||
	sin6_port     uint8
 | 
						sin6_port     uint8  // nolint:unused
 | 
				
			||||||
	sin6_flowinfo uint32
 | 
						sin6_flowinfo uint32 // nolint:unused
 | 
				
			||||||
	sin6_addr     [8]uint16
 | 
						sin6_addr     [8]uint16
 | 
				
			||||||
	sin6_scope_id uint32
 | 
						sin6_scope_id uint32 // nolint:unused
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// nolint:structcheck
 | 
				
			||||||
type in6_aliasreq struct {
 | 
					type in6_aliasreq struct {
 | 
				
			||||||
	ifra_name       [16]byte
 | 
						ifra_name       [16]byte
 | 
				
			||||||
	ifra_addr       sockaddr_in6
 | 
						ifra_addr       sockaddr_in6
 | 
				
			||||||
	ifra_dstaddr    sockaddr_in6
 | 
						ifra_dstaddr    sockaddr_in6 // nolint:unused
 | 
				
			||||||
	ifra_prefixmask sockaddr_in6
 | 
						ifra_prefixmask sockaddr_in6
 | 
				
			||||||
	ifra_flags      uint32
 | 
						ifra_flags      uint32
 | 
				
			||||||
	ifra_lifetime   in6_addrlifetime
 | 
						ifra_lifetime   in6_addrlifetime
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2,14 +2,14 @@ package tuntap
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Out-of-band packet types
 | 
					// Out-of-band packet types
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	typeKeyDummy = iota
 | 
						typeKeyDummy = iota // nolint:deadcode,varcheck
 | 
				
			||||||
	typeKeyLookup
 | 
						typeKeyLookup
 | 
				
			||||||
	typeKeyResponse
 | 
						typeKeyResponse
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// In-band packet types
 | 
					// In-band packet types
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
	typeSessionDummy = iota
 | 
						typeSessionDummy = iota // nolint:deadcode,varcheck
 | 
				
			||||||
	typeSessionTraffic
 | 
						typeSessionTraffic
 | 
				
			||||||
	typeSessionProto
 | 
						typeSessionProto
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue