diff --git a/cmd/yggdrasil/main.go b/cmd/yggdrasil/main.go index f8d882d..f239ed3 100644 --- a/cmd/yggdrasil/main.go +++ b/cmd/yggdrasil/main.go @@ -38,7 +38,6 @@ import ( type node struct { core *core.Core - config *config.NodeConfig tuntap *tuntap.TunAdapter multicast *multicast.Multicast admin *admin.AdminSocket @@ -326,7 +325,7 @@ func run(args yggArgs, ctx context.Context, done chan struct{}) { default: } - n := &node{config: cfg} + n := &node{} // Setup the Yggdrasil node itself. { @@ -390,15 +389,22 @@ func run(args yggArgs, ctx context.Context, done chan struct{}) { } } - // Start the TUN/TAP interface - n.tuntap = &tuntap.TunAdapter{} - 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) + // Setup the TUN module. + { + options := []tuntap.SetupOption{ + tuntap.InterfaceName(cfg.IfName), + tuntap.InterfaceMTU(cfg.IfMTU), + } + rwc := ipv6rwc.NewReadWriteCloser(n.core) + n.tuntap, err = tuntap.New(rwc, logger, options...) + if err != nil { + panic(err) + } + if n.admin != nil { + n.tuntap.SetupAdminHandlers(n.admin) + } } - n.tuntap.SetupAdminHandlers(n.admin) + // Make some nice output that tells us what our IPv6 address and subnet are. // This is just logged to stdout for the user. address := n.core.Address() diff --git a/src/multicast/multicast.go b/src/multicast/multicast.go index b6d290e..24e9d04 100644 --- a/src/multicast/multicast.go +++ b/src/multicast/multicast.go @@ -80,8 +80,8 @@ func (m *Multicast) _start() error { if len(m.config._interfaces) == 0 { return nil } - m.log.Infoln("Starting multicast module") - defer m.log.Infoln("Started multicast module") + m.log.Debugln("Starting multicast module") + defer m.log.Debugln("Started multicast module") addr, err := net.ResolveUDPAddr("udp", string(m.config._groupAddr)) if err != nil { return err diff --git a/src/tuntap/options.go b/src/tuntap/options.go new file mode 100644 index 0000000..10af8d9 --- /dev/null +++ b/src/tuntap/options.go @@ -0,0 +1,20 @@ +package tuntap + +func (m *TunAdapter) _applyOption(opt SetupOption) { + switch v := opt.(type) { + case InterfaceName: + m.config.name = v + case InterfaceMTU: + m.config.mtu = v + } +} + +type SetupOption interface { + isSetupOption() +} + +type InterfaceName string +type InterfaceMTU uint64 + +func (a InterfaceName) isSetupOption() {} +func (a InterfaceMTU) isSetupOption() {} diff --git a/src/tuntap/tun.go b/src/tuntap/tun.go index eddccbc..b0c444f 100644 --- a/src/tuntap/tun.go +++ b/src/tuntap/tun.go @@ -16,13 +16,12 @@ import ( //"sync" "github.com/Arceliar/phony" - "github.com/gologme/log" "golang.zx2c4.com/wireguard/tun" "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" + "github.com/yggdrasil-network/yggdrasil-go/src/util" ) type MTU uint16 @@ -33,8 +32,7 @@ type MTU uint16 // calling yggdrasil.Start(). type TunAdapter struct { rwc *ipv6rwc.ReadWriteCloser - config *config.NodeConfig - log *log.Logger + log util.Logger addr address.Address subnet address.Subnet mtu uint64 @@ -43,6 +41,10 @@ type TunAdapter struct { //mutex sync.RWMutex // Protects the below isOpen bool isEnabled bool // Used by the writer to drop sessionTraffic if not enabled + config struct { + name InterfaceName + mtu InterfaceMTU + } } // Gets the maximum supported MTU for the platform based on the defaults in @@ -93,50 +95,39 @@ 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 { - tun.rwc = rwc - tun.config = config - tun.log = log - return nil -} - -// Start the setup process for the TUN adapter. If successful, starts the -// reader actor to handle packets on that interface. -func (tun *TunAdapter) Start() error { - var err error - phony.Block(tun, func() { - err = tun._start() - }) - return err +func New(rwc *ipv6rwc.ReadWriteCloser, log util.Logger, opts ...SetupOption) (*TunAdapter, error) { + tun := &TunAdapter{ + rwc: rwc, + log: log, + } + for _, opt := range opts { + tun._applyOption(opt) + } + return tun, tun._start() } func (tun *TunAdapter) _start() error { if tun.isOpen { return errors.New("TUN module is already started") } - 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) - if tun.config.IfName == "none" || tun.config.IfName == "dummy" { + if tun.config.name == "none" || tun.config.name == "dummy" { tun.log.Debugln("Not starting TUN as ifname is none or dummy") tun.isEnabled = false go tun.write() return nil } - mtu := tun.config.IfMTU + mtu := uint64(tun.config.mtu) if tun.rwc.MaxMTU() < mtu { mtu = tun.rwc.MaxMTU() } - if err := tun.setup(tun.config.IfName, addr, mtu); err != nil { + if err := tun.setup(string(tun.config.name), addr, mtu); err != nil { return err } 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.log.Warnf("Warning: Interface MTU %d automatically adjusted to %d (supported range is 1280-%d)", tun.config.mtu, tun.MTU(), MaximumMTU()) } tun.rwc.SetMTU(tun.MTU()) tun.isOpen = true