Merge pull request #583 from neilalexander/modules

Define module.Module interface
This commit is contained in:
Arceliar 2019-10-24 21:48:05 -05:00 committed by GitHub
commit 97a85e1d44
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 93 additions and 43 deletions

View file

@ -25,12 +25,12 @@ import (
// TODO: Add authentication
type AdminSocket struct {
core *yggdrasil.Core
log *log.Logger
reconfigure chan chan error
listenaddr string
listener net.Listener
handlers map[string]handler
core *yggdrasil.Core
log *log.Logger
listenaddr string
listener net.Listener
handlers map[string]handler
started bool
}
// 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.
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.log = log
a.reconfigure = make(chan chan error, 1)
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()
a.listenaddr = current.AdminListen
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 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) {
ip := c.Address().String()
subnet := c.Subnet()
ip := a.core.Address().String()
subnet := a.core.Subnet()
return Info{
"self": Info{
ip: Info{
"box_pub_key": c.EncryptionPublicKey(),
"box_pub_key": a.core.EncryptionPublicKey(),
"build_name": version.BuildName(),
"build_version": version.BuildVersion(),
"coords": fmt.Sprintf("%v", c.Coords()),
"coords": fmt.Sprintf("%v", a.core.Coords()),
"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 {
if a.listenaddr != "none" && a.listenaddr != "" {
go a.listen()
a.started = true
}
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 {
if a.listener != nil {
a.started = false
return a.listener.Close()
} else {
return nil

20
src/module/module.go Normal file
View 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
}

View file

@ -56,6 +56,11 @@ type TunAdapter struct {
isOpen bool
}
type TunOptions struct {
Listener *yggdrasil.Listener
Dialer *yggdrasil.Dialer
}
// Gets the maximum supported MTU for the platform based on the defaults in
// defaults.GetDefaults().
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
// 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.log = log
tun.listener = listener
tun.dialer = dialer
tun.listener = tunoptions.Listener
tun.dialer = tunoptions.Dialer
tun.addrToConn = make(map[address.Address]*tunConn)
tun.subnetToConn = make(map[address.Subnet]*tunConn)
tun.dials = make(map[string][][]byte)
tun.writer.tun = tun
tun.reader.tun = tun
return nil
}
// 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 {
if tun.isOpen {
return errors.New("TUN/TAP module is already started")
}
current := tun.config.GetCurrent()
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
boxPubHex, err := hex.DecodeString(current.EncryptionPublicKey)
@ -160,13 +173,6 @@ func (tun *TunAdapter) _start() error {
return nil
}
tun.isOpen = true
tun.reconfigure = make(chan chan error)
go func() {
for {
e := <-tun.reconfigure
e <- nil
}
}()
go tun.handler()
tun.reader.Act(nil, tun.reader._read) // Start the reader
tun.icmpv6.Init(tun)
@ -177,6 +183,15 @@ func (tun *TunAdapter) _start() error {
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
// read/write goroutines to handle packets on that interface.
func (tun *TunAdapter) Stop() error {