mirror of
				https://github.com/yggdrasil-network/yggdrasil-go.git
				synced 2025-11-04 03:05:07 +03:00 
			
		
		
		
	Merge pull request #583 from neilalexander/modules
Define module.Module interface
This commit is contained in:
		
						commit
						97a85e1d44
					
				
					 4 changed files with 93 additions and 43 deletions
				
			
		| 
						 | 
					@ -23,6 +23,7 @@ import (
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/admin"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/admin"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/crypto"
 | 
				
			||||||
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/module"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/multicast"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/tuntap"
 | 
				
			||||||
	"github.com/yggdrasil-network/yggdrasil-go/src/version"
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/version"
 | 
				
			||||||
| 
						 | 
					@ -32,9 +33,9 @@ import (
 | 
				
			||||||
type node struct {
 | 
					type node struct {
 | 
				
			||||||
	core      yggdrasil.Core
 | 
						core      yggdrasil.Core
 | 
				
			||||||
	state     *config.NodeState
 | 
						state     *config.NodeState
 | 
				
			||||||
	tuntap    tuntap.TunAdapter
 | 
						tuntap    module.Module // tuntap.TunAdapter
 | 
				
			||||||
	multicast multicast.Multicast
 | 
						multicast module.Module // multicast.Multicast
 | 
				
			||||||
	admin     admin.AdminSocket
 | 
						admin     module.Module // admin.AdminSocket
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config.NodeConfig {
 | 
					func readConfig(useconf *bool, useconffile *string, normaliseconf *bool) *config.NodeConfig {
 | 
				
			||||||
| 
						 | 
					@ -231,25 +232,30 @@ func main() {
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Register the session firewall gatekeeper function
 | 
						// Register the session firewall gatekeeper function
 | 
				
			||||||
	n.core.SetSessionGatekeeper(n.sessionFirewall)
 | 
						n.core.SetSessionGatekeeper(n.sessionFirewall)
 | 
				
			||||||
 | 
						// Allocate our modules
 | 
				
			||||||
 | 
						n.admin = &admin.AdminSocket{}
 | 
				
			||||||
 | 
						n.multicast = &multicast.Multicast{}
 | 
				
			||||||
 | 
						n.tuntap = &tuntap.TunAdapter{}
 | 
				
			||||||
	// Start the admin socket
 | 
						// Start the admin socket
 | 
				
			||||||
	n.admin.Init(&n.core, n.state, logger, nil)
 | 
						n.admin.Init(&n.core, n.state, logger, nil)
 | 
				
			||||||
	if err := n.admin.Start(); err != nil {
 | 
						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))
 | 
				
			||||||
	// Start the multicast interface
 | 
						// Start the multicast interface
 | 
				
			||||||
	n.multicast.Init(&n.core, n.state, logger, nil)
 | 
						n.multicast.Init(&n.core, n.state, logger, nil)
 | 
				
			||||||
	if err := n.multicast.Start(); err != nil {
 | 
						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)
 | 
						n.multicast.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
				
			||||||
	// Start the TUN/TAP interface
 | 
						// Start the TUN/TAP interface
 | 
				
			||||||
	if listener, err := n.core.ConnListen(); err == nil {
 | 
						if listener, err := n.core.ConnListen(); err == nil {
 | 
				
			||||||
		if dialer, err := n.core.ConnDialer(); err == nil {
 | 
							if dialer, err := n.core.ConnDialer(); err == nil {
 | 
				
			||||||
			n.tuntap.Init(n.state, logger, listener, dialer)
 | 
								n.tuntap.Init(&n.core, n.state, logger, tuntap.TunOptions{Listener: listener, Dialer: dialer})
 | 
				
			||||||
			if err := n.tuntap.Start(); err != nil {
 | 
								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)
 | 
								n.tuntap.SetupAdminHandlers(n.admin.(*admin.AdminSocket))
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			logger.Errorln("Unable to get Dialer:", err)
 | 
								logger.Errorln("Unable to get Dialer:", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -25,12 +25,12 @@ import (
 | 
				
			||||||
// TODO: Add authentication
 | 
					// TODO: Add authentication
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type AdminSocket struct {
 | 
					type AdminSocket struct {
 | 
				
			||||||
	core        *yggdrasil.Core
 | 
						core       *yggdrasil.Core
 | 
				
			||||||
	log         *log.Logger
 | 
						log        *log.Logger
 | 
				
			||||||
	reconfigure chan chan error
 | 
						listenaddr string
 | 
				
			||||||
	listenaddr  string
 | 
						listener   net.Listener
 | 
				
			||||||
	listener    net.Listener
 | 
						handlers   map[string]handler
 | 
				
			||||||
	handlers    map[string]handler
 | 
						started    bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Info refers to information that is returned to the admin socket handler.
 | 
					// Info refers to information that is returned to the admin socket handler.
 | 
				
			||||||
| 
						 | 
					@ -54,23 +54,10 @@ func (a *AdminSocket) AddHandler(name string, args []string, handlerfunc func(In
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// init runs the initial admin setup.
 | 
					// init runs the initial admin setup.
 | 
				
			||||||
func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.Logger, options interface{}) {
 | 
					func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.Logger, options interface{}) error {
 | 
				
			||||||
	a.core = c
 | 
						a.core = c
 | 
				
			||||||
	a.log = log
 | 
						a.log = log
 | 
				
			||||||
	a.reconfigure = make(chan chan error, 1)
 | 
					 | 
				
			||||||
	a.handlers = make(map[string]handler)
 | 
						a.handlers = make(map[string]handler)
 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		for {
 | 
					 | 
				
			||||||
			e := <-a.reconfigure
 | 
					 | 
				
			||||||
			current, previous := state.GetCurrent(), state.GetPrevious()
 | 
					 | 
				
			||||||
			if current.AdminListen != previous.AdminListen {
 | 
					 | 
				
			||||||
				a.listenaddr = current.AdminListen
 | 
					 | 
				
			||||||
				a.Stop()
 | 
					 | 
				
			||||||
				a.Start()
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			e <- nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	current := state.GetCurrent()
 | 
						current := state.GetCurrent()
 | 
				
			||||||
	a.listenaddr = current.AdminListen
 | 
						a.listenaddr = current.AdminListen
 | 
				
			||||||
	a.AddHandler("list", []string{}, func(in Info) (Info, error) {
 | 
						a.AddHandler("list", []string{}, func(in Info) (Info, error) {
 | 
				
			||||||
| 
						 | 
					@ -80,16 +67,31 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return Info{"list": handlers}, nil
 | 
							return Info{"list": handlers}, nil
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *AdminSocket) UpdateConfig(config *config.NodeConfig) {
 | 
				
			||||||
 | 
						a.log.Debugln("Reloading admin configuration...")
 | 
				
			||||||
 | 
						if a.listenaddr != config.AdminListen {
 | 
				
			||||||
 | 
							a.listenaddr = config.AdminListen
 | 
				
			||||||
 | 
							if a.IsStarted() {
 | 
				
			||||||
 | 
								a.Stop()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							a.Start()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (a *AdminSocket) SetupAdminHandlers(na *AdminSocket) {
 | 
				
			||||||
	a.AddHandler("getSelf", []string{}, func(in Info) (Info, error) {
 | 
						a.AddHandler("getSelf", []string{}, func(in Info) (Info, error) {
 | 
				
			||||||
		ip := c.Address().String()
 | 
							ip := a.core.Address().String()
 | 
				
			||||||
		subnet := c.Subnet()
 | 
							subnet := a.core.Subnet()
 | 
				
			||||||
		return Info{
 | 
							return Info{
 | 
				
			||||||
			"self": Info{
 | 
								"self": Info{
 | 
				
			||||||
				ip: Info{
 | 
									ip: Info{
 | 
				
			||||||
					"box_pub_key":   c.EncryptionPublicKey(),
 | 
										"box_pub_key":   a.core.EncryptionPublicKey(),
 | 
				
			||||||
					"build_name":    version.BuildName(),
 | 
										"build_name":    version.BuildName(),
 | 
				
			||||||
					"build_version": version.BuildVersion(),
 | 
										"build_version": version.BuildVersion(),
 | 
				
			||||||
					"coords":        fmt.Sprintf("%v", c.Coords()),
 | 
										"coords":        fmt.Sprintf("%v", a.core.Coords()),
 | 
				
			||||||
					"subnet":        subnet.String(),
 | 
										"subnet":        subnet.String(),
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
| 
						 | 
					@ -312,17 +314,24 @@ func (a *AdminSocket) Init(c *yggdrasil.Core, state *config.NodeState, log *log.
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// start runs the admin API socket to listen for / respond to admin API calls.
 | 
					// Start runs the admin API socket to listen for / respond to admin API calls.
 | 
				
			||||||
func (a *AdminSocket) Start() error {
 | 
					func (a *AdminSocket) Start() error {
 | 
				
			||||||
	if a.listenaddr != "none" && a.listenaddr != "" {
 | 
						if a.listenaddr != "none" && a.listenaddr != "" {
 | 
				
			||||||
		go a.listen()
 | 
							go a.listen()
 | 
				
			||||||
 | 
							a.started = true
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// cleans up when stopping
 | 
					// IsStarted returns true if the module has been started.
 | 
				
			||||||
 | 
					func (a *AdminSocket) IsStarted() bool {
 | 
				
			||||||
 | 
						return a.started
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Stop will stop the admin API and close the socket.
 | 
				
			||||||
func (a *AdminSocket) Stop() error {
 | 
					func (a *AdminSocket) Stop() error {
 | 
				
			||||||
	if a.listener != nil {
 | 
						if a.listener != nil {
 | 
				
			||||||
 | 
							a.started = false
 | 
				
			||||||
		return a.listener.Close()
 | 
							return a.listener.Close()
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										20
									
								
								src/module/module.go
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								src/module/module.go
									
										
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,20 @@
 | 
				
			||||||
 | 
					package module
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"github.com/gologme/log"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/admin"
 | 
				
			||||||
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/config"
 | 
				
			||||||
 | 
						"github.com/yggdrasil-network/yggdrasil-go/src/yggdrasil"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Module is an interface that defines which functions must be supported by a
 | 
				
			||||||
 | 
					// given Yggdrasil module.
 | 
				
			||||||
 | 
					type Module interface {
 | 
				
			||||||
 | 
						Init(core *yggdrasil.Core, state *config.NodeState, log *log.Logger, options interface{}) error
 | 
				
			||||||
 | 
						Start() error
 | 
				
			||||||
 | 
						Stop() error
 | 
				
			||||||
 | 
						UpdateConfig(config *config.NodeConfig)
 | 
				
			||||||
 | 
						SetupAdminHandlers(a *admin.AdminSocket)
 | 
				
			||||||
 | 
						IsStarted() bool
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -56,6 +56,11 @@ type TunAdapter struct {
 | 
				
			||||||
	isOpen       bool
 | 
						isOpen       bool
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type TunOptions struct {
 | 
				
			||||||
 | 
						Listener *yggdrasil.Listener
 | 
				
			||||||
 | 
						Dialer   *yggdrasil.Dialer
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gets the maximum supported MTU for the platform based on the defaults in
 | 
					// Gets the maximum supported MTU for the platform based on the defaults in
 | 
				
			||||||
// defaults.GetDefaults().
 | 
					// defaults.GetDefaults().
 | 
				
			||||||
func getSupportedMTU(mtu int) int {
 | 
					func getSupportedMTU(mtu int) int {
 | 
				
			||||||
| 
						 | 
					@ -110,16 +115,21 @@ func MaximumMTU() int {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Init initialises the TUN/TAP module. You must have acquired a Listener from
 | 
					// Init initialises the TUN/TAP 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(config *config.NodeState, log *log.Logger, listener *yggdrasil.Listener, dialer *yggdrasil.Dialer) {
 | 
					func (tun *TunAdapter) Init(core *yggdrasil.Core, config *config.NodeState, log *log.Logger, options interface{}) error {
 | 
				
			||||||
 | 
						tunoptions, ok := options.(TunOptions)
 | 
				
			||||||
 | 
						if !ok {
 | 
				
			||||||
 | 
							return fmt.Errorf("invalid options supplied to TunAdapter module")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	tun.config = config
 | 
						tun.config = config
 | 
				
			||||||
	tun.log = log
 | 
						tun.log = log
 | 
				
			||||||
	tun.listener = listener
 | 
						tun.listener = tunoptions.Listener
 | 
				
			||||||
	tun.dialer = dialer
 | 
						tun.dialer = tunoptions.Dialer
 | 
				
			||||||
	tun.addrToConn = make(map[address.Address]*tunConn)
 | 
						tun.addrToConn = make(map[address.Address]*tunConn)
 | 
				
			||||||
	tun.subnetToConn = make(map[address.Subnet]*tunConn)
 | 
						tun.subnetToConn = make(map[address.Subnet]*tunConn)
 | 
				
			||||||
	tun.dials = make(map[string][][]byte)
 | 
						tun.dials = make(map[string][][]byte)
 | 
				
			||||||
	tun.writer.tun = tun
 | 
						tun.writer.tun = tun
 | 
				
			||||||
	tun.reader.tun = tun
 | 
						tun.reader.tun = tun
 | 
				
			||||||
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Start the setup process for the TUN/TAP adapter. If successful, starts the
 | 
					// Start the setup process for the TUN/TAP adapter. If successful, starts the
 | 
				
			||||||
| 
						 | 
					@ -133,9 +143,12 @@ func (tun *TunAdapter) Start() error {
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (tun *TunAdapter) _start() error {
 | 
					func (tun *TunAdapter) _start() error {
 | 
				
			||||||
 | 
						if tun.isOpen {
 | 
				
			||||||
 | 
							return errors.New("TUN/TAP module is already started")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	current := tun.config.GetCurrent()
 | 
						current := tun.config.GetCurrent()
 | 
				
			||||||
	if tun.config == nil || tun.listener == nil || tun.dialer == nil {
 | 
						if tun.config == nil || tun.listener == nil || tun.dialer == nil {
 | 
				
			||||||
		return errors.New("No configuration available to TUN/TAP")
 | 
							return errors.New("no configuration available to TUN/TAP")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var boxPub crypto.BoxPubKey
 | 
						var boxPub crypto.BoxPubKey
 | 
				
			||||||
	boxPubHex, err := hex.DecodeString(current.EncryptionPublicKey)
 | 
						boxPubHex, err := hex.DecodeString(current.EncryptionPublicKey)
 | 
				
			||||||
| 
						 | 
					@ -160,13 +173,6 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	tun.isOpen = true
 | 
						tun.isOpen = true
 | 
				
			||||||
	tun.reconfigure = make(chan chan error)
 | 
					 | 
				
			||||||
	go func() {
 | 
					 | 
				
			||||||
		for {
 | 
					 | 
				
			||||||
			e := <-tun.reconfigure
 | 
					 | 
				
			||||||
			e <- nil
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}()
 | 
					 | 
				
			||||||
	go tun.handler()
 | 
						go tun.handler()
 | 
				
			||||||
	tun.reader.Act(nil, tun.reader._read) // Start the reader
 | 
						tun.reader.Act(nil, tun.reader._read) // Start the reader
 | 
				
			||||||
	tun.icmpv6.Init(tun)
 | 
						tun.icmpv6.Init(tun)
 | 
				
			||||||
| 
						 | 
					@ -177,6 +183,15 @@ func (tun *TunAdapter) _start() error {
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// IsStarted returns true if the module has been started.
 | 
				
			||||||
 | 
					func (tun *TunAdapter) IsStarted() bool {
 | 
				
			||||||
 | 
						var isOpen bool
 | 
				
			||||||
 | 
						phony.Block(tun, func() {
 | 
				
			||||||
 | 
							isOpen = tun.isOpen
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						return isOpen
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Start the setup process for the TUN/TAP adapter. If successful, starts the
 | 
					// Start the setup process for the TUN/TAP adapter. If successful, starts the
 | 
				
			||||||
// read/write goroutines to handle packets on that interface.
 | 
					// read/write goroutines to handle packets on that interface.
 | 
				
			||||||
func (tun *TunAdapter) Stop() error {
 | 
					func (tun *TunAdapter) Stop() error {
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue